summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-11-02 12:49:19 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-11-02 12:49:19 +0200
commit09a1f0075a8d5752dd7b2940a20d86a040af1741 (patch)
tree42c96cf95d5df2950b77329c76c0024f33088aff
parente6f95b23f425001a14a528256354e0faf4e272f6 (diff)
parent440d4b282dd4992d64abdd6289859598db7e5f75 (diff)
downloadmariadb-git-09a1f0075a8d5752dd7b2940a20d86a040af1741.tar.gz
Merge 10.5 into 10.6
-rw-r--r--.gitignore1
-rw-r--r--appveyor.yml4
-rw-r--r--client/mysql_upgrade.c4
-rw-r--r--client/mysqldump.c78
-rw-r--r--cmake/check_linker_flag.cmake6
-rw-r--r--cmake/jemalloc.cmake2
-rw-r--r--cmake/libutils.cmake13
-rw-r--r--cmake/os/Windows.cmake9
-rw-r--r--cmake/ssl.cmake2
-rw-r--r--configure.cmake3
-rwxr-xr-xdebian/additions/mariadb-report2
-rw-r--r--debian/mariadb-plugin-columnstore.install1
-rw-r--r--debian/mariadb-server-10.6.install1
-rw-r--r--debian/mariadb-server-10.6.mysql-server.logrotate2
-rw-r--r--debian/mariadb-server-10.6.postinst13
-rw-r--r--debian/mariadb-test.install1
-rwxr-xr-xdebian/rules1
-rw-r--r--extra/aws_sdk/CMakeLists.txt2
-rw-r--r--extra/mariabackup/backup_copy.cc4
-rw-r--r--extra/mariabackup/backup_copy.h4
-rw-r--r--extra/mariabackup/backup_mysql.cc3
-rw-r--r--extra/mariabackup/fil_cur.cc28
-rw-r--r--extra/mariabackup/xtrabackup.cc294
-rw-r--r--include/m_ctype.h2
-rw-r--r--include/my_pthread.h10
-rw-r--r--include/my_sys.h9
-rw-r--r--include/mysql/psi/mysql_thread.h2
-rw-r--r--include/mysql_version.h.in7
m---------libmariadb0
-rw-r--r--libmysqld/CMakeLists.txt2
-rw-r--r--libmysqld/lib_sql.cc3
-rw-r--r--man/mysqlimport.126
-rw-r--r--mysql-test/include/have_static_innodb.inc7
-rw-r--r--mysql-test/include/icp_debug_kill.inc50
-rw-r--r--mysql-test/include/mtr_check.sql1
-rw-r--r--mysql-test/include/not_true.require2
-rw-r--r--mysql-test/include/rowid_filter_debug_kill.inc68
-rw-r--r--mysql-test/lib/My/SafeProcess/CMakeLists.txt2
-rw-r--r--mysql-test/lib/mtr_cases.pm2
-rw-r--r--mysql-test/main/alter_table.result34
-rw-r--r--mysql-test/main/alter_table.test26
-rw-r--r--mysql-test/main/aria_icp_debug.result34
-rw-r--r--mysql-test/main/aria_icp_debug.test5
-rw-r--r--mysql-test/main/backup_locks.result121
-rw-r--r--mysql-test/main/backup_locks.test142
-rw-r--r--mysql-test/main/blackhole.result6
-rw-r--r--mysql-test/main/blackhole.test16
-rw-r--r--mysql-test/main/bootstrap_innodb.result8
-rw-r--r--mysql-test/main/bootstrap_innodb.test27
-rw-r--r--mysql-test/main/case.result6
-rw-r--r--mysql-test/main/derived_cond_pushdown.result16
-rw-r--r--mysql-test/main/errors.result35
-rw-r--r--mysql-test/main/errors.test36
-rw-r--r--mysql-test/main/func_group.result4
-rw-r--r--mysql-test/main/func_json.result10
-rw-r--r--mysql-test/main/func_json.test5
-rw-r--r--mysql-test/main/func_math.result5
-rw-r--r--mysql-test/main/func_math.test5
-rw-r--r--mysql-test/main/func_test.result19
-rw-r--r--mysql-test/main/func_test.test17
-rw-r--r--mysql-test/main/grant5.result36
-rw-r--r--mysql-test/main/grant5.test21
-rw-r--r--mysql-test/main/implicit_commit.result10
-rw-r--r--mysql-test/main/implicit_commit.test10
-rw-r--r--mysql-test/main/index_intersect_innodb.result8
-rw-r--r--mysql-test/main/index_merge_myisam.result2
-rw-r--r--mysql-test/main/innodb_ext_key,off.rdiff51
-rw-r--r--mysql-test/main/innodb_ext_key.result20
-rw-r--r--mysql-test/main/innodb_ext_key.test9
-rw-r--r--mysql-test/main/innodb_icp_debug.result34
-rw-r--r--mysql-test/main/innodb_icp_debug.test6
-rw-r--r--mysql-test/main/kill.result6
-rw-r--r--mysql-test/main/kill.test2
-rw-r--r--mysql-test/main/limit_rows_examined.result16
-rw-r--r--mysql-test/main/limit_rows_examined.test19
-rw-r--r--mysql-test/main/lock_view.result231
-rw-r--r--mysql-test/main/lock_view.test76
-rw-r--r--mysql-test/main/log_tables.result8
-rw-r--r--mysql-test/main/log_tables.test20
-rw-r--r--mysql-test/main/multi_update_big.result3
-rw-r--r--mysql-test/main/multi_update_big.test21
-rw-r--r--mysql-test/main/myisam_icp_debug.result32
-rw-r--r--mysql-test/main/myisam_icp_debug.test1
-rw-r--r--mysql-test/main/mysql_json_table_recreate.opt1
-rw-r--r--mysql-test/main/mysql_json_table_recreate.result171
-rw-r--r--mysql-test/main/mysql_json_table_recreate.test93
-rw-r--r--mysql-test/main/mysql_upgrade.result126
-rw-r--r--mysql-test/main/mysql_upgrade.test31
-rw-r--r--mysql-test/main/mysql_upgrade_mysql_json_datatype.result106
-rw-r--r--mysql-test/main/mysql_upgrade_mysql_json_datatype.test67
-rw-r--r--mysql-test/main/mysqldump.result118
-rw-r--r--mysql-test/main/mysqldump.test83
-rw-r--r--mysql-test/main/opt_trace_index_merge_innodb.result6
-rw-r--r--mysql-test/main/order_by.result141
-rw-r--r--mysql-test/main/order_by.test41
-rw-r--r--mysql-test/main/parser.result19
-rw-r--r--mysql-test/main/parser.test16
-rw-r--r--mysql-test/main/parser_precedence.result748
-rw-r--r--mysql-test/main/parser_precedence.test335
-rw-r--r--mysql-test/main/partition.result11
-rw-r--r--mysql-test/main/partition.test16
-rw-r--r--mysql-test/main/plugin_innodb.test9
-rw-r--r--mysql-test/main/pool_of_threads.result11
-rw-r--r--mysql-test/main/pool_of_threads.test8
-rw-r--r--mysql-test/main/precedence.result8019
-rw-r--r--mysql-test/main/precedence.test4788
-rw-r--r--mysql-test/main/precedence_bugs.result60
-rw-r--r--mysql-test/main/precedence_bugs.test41
-rw-r--r--mysql-test/main/processlist_notembedded.result13
-rw-r--r--mysql-test/main/processlist_notembedded.test18
-rw-r--r--mysql-test/main/range.result82
-rw-r--r--mysql-test/main/range.test50
-rw-r--r--mysql-test/main/range_mrr_icp.result82
-rw-r--r--mysql-test/main/range_vs_index_merge_innodb.result2
-rw-r--r--mysql-test/main/rowid_filter.result24
-rw-r--r--mysql-test/main/rowid_filter.test8
-rw-r--r--mysql-test/main/rowid_filter_innodb.result24
-rw-r--r--mysql-test/main/rowid_filter_innodb_debug.result83
-rw-r--r--mysql-test/main/rowid_filter_innodb_debug.test51
-rw-r--r--mysql-test/main/rowid_filter_myisam_debug.result54
-rw-r--r--mysql-test/main/rowid_filter_myisam_debug.test3
-rw-r--r--mysql-test/main/set_statement_notembedded.result5
-rw-r--r--mysql-test/main/set_statement_notembedded.test3
-rw-r--r--mysql-test/main/sp-destruct.result42
-rw-r--r--mysql-test/main/sp-destruct.test6
-rw-r--r--mysql-test/main/sp.result6
-rw-r--r--mysql-test/main/sp.test2
-rw-r--r--mysql-test/main/stat_tables_innodb.result4
-rw-r--r--mysql-test/main/subselect4.result2
-rw-r--r--mysql-test/main/sum_distinct-big.result37
-rw-r--r--mysql-test/main/sum_distinct-big.test32
-rw-r--r--mysql-test/main/temp_table_symlink.test2
-rw-r--r--mysql-test/main/type_blob.result15
-rw-r--r--mysql-test/main/type_blob.test20
-rw-r--r--mysql-test/main/type_newdecimal.result5
-rw-r--r--mysql-test/main/type_ranges.result6
-rw-r--r--mysql-test/main/udf.result21
-rw-r--r--mysql-test/main/udf.test30
-rw-r--r--mysql-test/main/view.result11
-rw-r--r--mysql-test/main/view.test11
-rwxr-xr-xmysql-test/mysql-test-run.pl30
-rw-r--r--mysql-test/std_data/mysql57user.MYDbin0 -> 340 bytes
-rw-r--r--mysql-test/std_data/mysql57user.MYIbin0 -> 4096 bytes
-rw-r--r--mysql-test/std_data/mysql57user.frmbin0 -> 10816 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test.MYDbin0 -> 1905700 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test.frmbin0 -> 8646 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test_big.MYDbin0 -> 1898044 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test_big.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/mysql_json/mysql_json_test_big.frmbin0 -> 8646 bytes
-rw-r--r--mysql-test/std_data/mysql_json/tempty.MYDbin0 -> 40 bytes
-rw-r--r--mysql-test/std_data/mysql_json/tempty.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/mysql_json/tempty.frmbin0 -> 8554 bytes
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result94
-rw-r--r--mysql-test/suite/binlog/r/binlog_recover_checksum_error.result8
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test14
-rw-r--r--mysql-test/suite/binlog/t/binlog_recover_checksum_error.test37
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-package.result42
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-package.test7
-rw-r--r--mysql-test/suite/encryption/r/innodb-page_encryption_compression.result18
-rw-r--r--mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result84
-rw-r--r--mysql-test/suite/encryption/r/tempfiles_encrypted.result3958
-rw-r--r--mysql-test/suite/encryption/t/innodb-page_encryption_compression.test15
-rw-r--r--mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test68
-rw-r--r--mysql-test/suite/encryption/t/innodb-remove-encryption.test3
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test5
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption-page-compression.test2
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt3
-rw-r--r--mysql-test/suite/encryption/t/tempfiles_encrypted.test26
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.result44
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.test57
-rw-r--r--mysql-test/suite/funcs_1/r/is_routines_embedded.result6
-rw-r--r--mysql-test/suite/galera/disabled.def4
-rw-r--r--mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result10
-rw-r--r--mysql-test/suite/galera/r/galera_load_data.result29
-rw-r--r--mysql-test/suite/galera/r/galera_sst_mariabackup_lost_found.result39
-rw-r--r--mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result133
-rw-r--r--mysql-test/suite/galera/r/galera_var_trx_fragment_size.result95
-rw-r--r--mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test10
-rw-r--r--mysql-test/suite/galera/t/galera_load_data.test28
-rw-r--r--mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.cnf15
-rw-r--r--mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test71
-rw-r--r--mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test80
-rw-r--r--mysql-test/suite/galera/t/galera_var_trx_fragment_size.test43
-rw-r--r--mysql-test/suite/galera_3nodes/disabled.def2
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_parallel_apply_3nodes.result10
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_parallel_apply_3nodes.test14
-rw-r--r--mysql-test/suite/galera_sr/r/MDEV-23623.result26
-rw-r--r--mysql-test/suite/galera_sr/t/MDEV-23623.test50
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_fk.result21
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_fk.test12
-rw-r--r--mysql-test/suite/innodb/include/wait_all_purged.inc27
-rw-r--r--mysql-test/suite/innodb/r/flush.result16
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result62
-rw-r--r--mysql-test/suite/innodb/r/ibuf_not_empty.result20
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter.result30
-rw-r--r--mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb-virtual-columns.result50
-rw-r--r--mysql-test/suite/innodb/r/innodb_scrub.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result15
-rw-r--r--mysql-test/suite/innodb/r/innodb_stats_drop_locked.result2
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_bugs.result23
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_crash.result2
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_index_rename.result36
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff5
-rw-r--r--mysql-test/suite/innodb/r/monitor.result15
-rw-r--r--mysql-test/suite/innodb/r/purge_secondary.result4
-rw-r--r--mysql-test/suite/innodb/r/redo_log_during_checkpoint.result1
-rw-r--r--mysql-test/suite/innodb/r/stats_persistent.result19
-rw-r--r--mysql-test/suite/innodb/r/table_definition_cache_debug.result2
-rw-r--r--mysql-test/suite/innodb/t/alter_large_dml.test2
-rw-r--r--mysql-test/suite/innodb/t/flush.opt1
-rw-r--r--mysql-test/suite/innodb/t/flush.test19
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test63
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.combinations4
-rw-r--r--mysql-test/suite/innodb/t/ibuf_not_empty.test25
-rw-r--r--mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb-trim.test12
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug30113362.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_scrub.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_drop_locked.test2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test17
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_crash.test2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_index_rename.test20
-rw-r--r--mysql-test/suite/innodb/t/purge_secondary.test3
-rw-r--r--mysql-test/suite/innodb/t/redo_log_during_checkpoint.test1
-rw-r--r--mysql-test/suite/innodb/t/stats_persistent.test27
-rw-r--r--mysql-test/suite/innodb/t/table_definition_cache_debug.test2
-rw-r--r--mysql-test/suite/innodb/t/temporary_table.test2
-rw-r--r--mysql-test/suite/innodb/t/undo_truncate_recover.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/t/basic.test20
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test42
-rw-r--r--mysql-test/suite/maria/alter.result80
-rw-r--r--mysql-test/suite/maria/alter.test102
-rw-r--r--mysql-test/suite/maria/create.result44
-rw-r--r--mysql-test/suite/maria/create.test55
-rw-r--r--mysql-test/suite/maria/maria-no-logging.result6
-rw-r--r--mysql-test/suite/maria/maria-no-logging.test2
-rw-r--r--mysql-test/suite/mariabackup/incremental_ddl_during_backup.result1
-rw-r--r--mysql-test/suite/mariabackup/incremental_ddl_during_backup.test6
-rw-r--r--mysql-test/suite/parts/r/reorganize.result13
-rw-r--r--mysql-test/suite/parts/t/reorganize.test20
-rw-r--r--mysql-test/suite/perfschema/r/dml_file_instances.result12
-rw-r--r--mysql-test/suite/perfschema/r/sxlock_func.result1
-rw-r--r--mysql-test/suite/perfschema/t/dml_file_instances.test3
-rw-r--r--mysql-test/suite/perfschema/t/show_sanity.test4
-rw-r--r--mysql-test/suite/period/r/delete.result21
-rw-r--r--mysql-test/suite/period/r/overlaps.result32
-rw-r--r--mysql-test/suite/period/r/update.result26
-rw-r--r--mysql-test/suite/period/t/delete.test31
-rw-r--r--mysql-test/suite/period/t/overlaps.test43
-rw-r--r--mysql-test/suite/period/t/update.test32
-rw-r--r--mysql-test/suite/plugins/r/server_audit.result55
-rw-r--r--mysql-test/suite/plugins/r/test_sql_service.result8
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test21
-rw-r--r--mysql-test/suite/plugins/t/test_sql_service.opt2
-rw-r--r--mysql-test/suite/plugins/t/test_sql_service.test18
-rw-r--r--mysql-test/suite/roles/set_default_role_clear.result1
-rw-r--r--mysql-test/suite/roles/set_default_role_for.result2
-rw-r--r--mysql-test/suite/roles/set_default_role_invalid.result3
-rw-r--r--mysql-test/suite/roles/set_default_role_new_connection.result2
-rw-r--r--mysql-test/suite/rpl/disabled.def1
-rw-r--r--mysql-test/suite/rpl/r/rpl_create_drop_view.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_mysql_upgrade.result58
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel_retry.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_start_stop_slave.result2
-rw-r--r--mysql-test/suite/rpl/t/rpl_create_drop_view.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test9
-rw-r--r--mysql-test/suite/rpl/t/rpl_mysql_upgrade.test34
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_retry.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_slave_grp_exec.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_start_stop_slave.test5
-rw-r--r--mysql-test/suite/s3/alter.result8
-rw-r--r--mysql-test/suite/s3/alter.test4
-rw-r--r--mysql-test/suite/s3/disabled.def3
-rw-r--r--mysql-test/suite/s3/my.cnf2
-rw-r--r--mysql-test/suite/s3/partition.result2
-rw-r--r--mysql-test/suite/s3/partition.test5
-rw-r--r--mysql-test/suite/s3/partition_move.test5
-rw-r--r--mysql-test/suite/s3/replication.inc10
-rw-r--r--mysql-test/suite/s3/replication_delayed.cnf3
-rw-r--r--mysql-test/suite/s3/replication_delayed.result124
-rw-r--r--mysql-test/suite/s3/replication_delayed.test115
-rw-r--r--mysql-test/suite/s3/replication_mixed.result27
-rw-r--r--mysql-test/suite/s3/replication_partition.result18
-rw-r--r--mysql-test/suite/s3/replication_partition.test22
-rw-r--r--mysql-test/suite/s3/replication_stmt.result27
-rw-r--r--mysql-test/suite/s3/slave.cnf7
-rw-r--r--mysql-test/suite/sql_sequence/mysqldump.result32
-rw-r--r--mysql-test/suite/sql_sequence/next.result14
-rw-r--r--mysql-test/suite/sql_sequence/next.test17
-rw-r--r--mysql-test/suite/sys_vars/r/div_precision_increment_func.result16
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_doublewrite_batch_size_basic.result24
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result34
-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.result16
-rw-r--r--mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff83
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result46
-rw-r--r--mysql-test/suite/sys_vars/r/wsrep_cluster_address_basic.result1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_doublewrite_batch_size_basic.test24
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test17
-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.test32
-rw-r--r--mysql-test/suite/sys_vars/t/session_track_system_variables_basic.test2
-rw-r--r--mysql-test/suite/sys_vars/t/wsrep_cluster_address_basic.test2
-rw-r--r--mysql-test/suite/vcol/r/not_supported.result2
-rw-r--r--mysql-test/suite/versioning/r/create.result56
-rw-r--r--mysql-test/suite/versioning/r/cte.result8
-rw-r--r--mysql-test/suite/versioning/r/derived.result4
-rw-r--r--mysql-test/suite/versioning/r/select.result31
-rw-r--r--mysql-test/suite/versioning/r/trx_id.result6
-rw-r--r--mysql-test/suite/versioning/r/view.result11
-rw-r--r--mysql-test/suite/versioning/t/create.test33
-rw-r--r--mysql-test/suite/versioning/t/select.test21
-rw-r--r--mysql-test/suite/versioning/t/view.test13
-rw-r--r--mysql-test/suite/wsrep/r/MDEV-23081.result24
-rw-r--r--mysql-test/suite/wsrep/r/mdev_22681.result3
-rw-r--r--mysql-test/suite/wsrep/r/variables.result5
-rw-r--r--mysql-test/suite/wsrep/r/variables_debug.result278
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23081.cnf9
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23081.combinations4
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23081.test57
-rw-r--r--mysql-test/suite/wsrep/t/mdev_22681.cnf10
-rw-r--r--mysql-test/suite/wsrep/t/mdev_22681.test15
-rw-r--r--mysql-test/suite/wsrep/t/variables.cnf7
-rw-r--r--mysql-test/suite/wsrep/t/variables.opt1
-rw-r--r--mysql-test/suite/wsrep/t/variables.test3
-rw-r--r--mysql-test/suite/wsrep/t/variables_debug.cnf7
-rw-r--r--mysql-test/suite/wsrep/t/variables_debug.test176
-rw-r--r--mysql-test/unstable-tests875
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/hash.c5
-rw-r--r--mysys/mf_iocache.c6
-rw-r--r--mysys/my_addr_resolve.c26
-rw-r--r--mysys/my_error.c3
-rw-r--r--mysys_ssl/openssl.c3
-rw-r--r--plugin/auth_gssapi/CMakeLists.txt5
-rw-r--r--plugin/auth_pam/CMakeLists.txt37
-rw-r--r--plugin/auth_pam/auth_pam.c3
-rw-r--r--plugin/auth_pam/auth_pam_base.c1
-rw-r--r--plugin/auth_pam/config.h.cmake5
-rw-r--r--plugin/auth_pam/mapper/pam_user_map.c30
-rw-r--r--plugin/auth_pam/testing/CMakeLists.txt6
-rw-r--r--plugin/aws_key_management/aws_key_management_plugin.cc4
-rw-r--r--plugin/server_audit/server_audit.c62
-rw-r--r--plugin/test_sql_service/CMakeLists.txt18
-rw-r--r--plugin/test_sql_service/COPYING339
-rw-r--r--plugin/test_sql_service/test_sql_service.c145
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result2
-rw-r--r--plugin/type_inet/plugin.cc2
-rw-r--r--plugin/type_mysql_json/CMakeLists.txt18
-rw-r--r--plugin/type_mysql_json/mysql_json.cc515
-rw-r--r--plugin/type_mysql_json/mysql_json.h45
-rw-r--r--plugin/type_mysql_json/type.cc216
-rwxr-xr-xscripts/convert-debug-for-diff.sh2
-rw-r--r--scripts/mysql_config.pl.in2
-rw-r--r--scripts/mysql_system_tables_fix.sql12
-rw-r--r--scripts/mysqld_safe.sh54
-rw-r--r--scripts/wsrep_sst_common.sh46
-rw-r--r--scripts/wsrep_sst_mariabackup.sh67
-rw-r--r--sql-common/client.c4
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/backup.cc6
-rw-r--r--sql/derived_handler.cc4
-rw-r--r--sql/field.h5
-rw-r--r--sql/filesort.cc29
-rw-r--r--sql/ha_partition.cc4
-rw-r--r--sql/handle_connections_win.cc66
-rw-r--r--sql/handler.cc157
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.h19
-rw-r--r--sql/item_cmpfunc.cc33
-rw-r--r--sql/item_cmpfunc.h19
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_geofunc.cc16
-rw-r--r--sql/item_jsonfunc.cc8
-rw-r--r--sql/item_jsonfunc.h3
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_subselect.h2
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/item_timefunc.h2
-rw-r--r--sql/log.cc73
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/log_event.h6
-rw-r--r--sql/log_event_client.cc10
-rw-r--r--sql/mf_iocache_encr.cc10
-rw-r--r--sql/my_decimal.h6
-rw-r--r--sql/mysqld.cc19
-rw-r--r--sql/opt_range.cc20
-rw-r--r--sql/opt_subselect.cc13
-rw-r--r--sql/opt_sum.cc24
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/select_handler.cc77
-rw-r--r--sql/select_handler.h20
-rw-r--r--sql/session_tracker.cc3
-rw-r--r--sql/set_var.cc3
-rw-r--r--sql/share/errmsg-utf8.txt15
-rw-r--r--sql/sp_head.cc3
-rw-r--r--sql/sql_acl.cc91
-rw-r--r--sql/sql_base.cc44
-rw-r--r--sql/sql_class.cc72
-rw-r--r--sql/sql_class.h28
-rw-r--r--sql/sql_delete.cc3
-rw-r--r--sql/sql_insert.cc109
-rw-r--r--sql/sql_insert.h10
-rw-r--r--sql/sql_lex.cc16
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_parse.cc136
-rw-r--r--sql/sql_parse.h2
-rw-r--r--sql/sql_prepare.cc266
-rw-r--r--sql/sql_reload.cc10
-rw-r--r--sql/sql_rename.cc3
-rw-r--r--sql/sql_select.cc62
-rw-r--r--sql/sql_select.h26
-rw-r--r--sql/sql_show.cc175
-rw-r--r--sql/sql_sort.h50
-rw-r--r--sql/sql_string.cc6
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_table.cc342
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_type.cc86
-rw-r--r--sql/sql_type.h61
-rw-r--r--sql/sql_udf.cc148
-rw-r--r--sql/sql_udf.h8
-rw-r--r--sql/sql_update.cc17
-rw-r--r--sql/sql_yacc.yy160
-rw-r--r--sql/sys_vars.ic8
-rw-r--r--sql/table.cc43
-rw-r--r--sql/table.h1
-rw-r--r--sql/threadpool_common.cc14
-rw-r--r--sql/wsrep_mysqld.h3
-rw-r--r--sql/wsrep_sst.cc42
-rw-r--r--sql/wsrep_var.cc3
-rw-r--r--sql/xa.cc2
-rw-r--r--storage/blackhole/ha_blackhole.h5
m---------storage/columnstore/columnstore0
-rw-r--r--storage/connect/filamzip.cpp1
-rw-r--r--storage/connect/global.h56
-rw-r--r--storage/connect/ha_connect.cc265
-rw-r--r--storage/connect/ha_connect.h4
-rw-r--r--storage/connect/json.cpp164
-rw-r--r--storage/connect/json.h57
-rw-r--r--storage/connect/jsonudf.cpp546
-rw-r--r--storage/connect/jsonudf.h39
-rw-r--r--storage/connect/mongo.cpp10
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_2.result36
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_3.result36
-rw-r--r--storage/connect/mysql-test/connect/r/json_mongo_c.result36
-rw-r--r--storage/connect/mysql-test/connect/r/updelx.result4
-rw-r--r--storage/connect/mysql-test/connect/t/updelx.test4
-rw-r--r--storage/connect/myutil.h4
-rw-r--r--storage/connect/plgdbutl.cpp20
-rw-r--r--storage/connect/plugutil.cpp67
-rw-r--r--storage/connect/tabjson.cpp110
-rw-r--r--storage/connect/tabjson.h4
-rw-r--r--storage/connect/tabrest.cpp28
-rw-r--r--storage/connect/tabxml.cpp9
-rw-r--r--storage/connect/user_connect.cc20
-rw-r--r--storage/connect/value.cpp9
-rw-r--r--storage/connect/value.h7
-rw-r--r--storage/heap/ha_heap.cc33
-rw-r--r--storage/innobase/CMakeLists.txt3
-rw-r--r--storage/innobase/btr/btr0btr.cc43
-rw-r--r--storage/innobase/btr/btr0bulk.cc29
-rw-r--r--storage/innobase/btr/btr0cur.cc350
-rw-r--r--storage/innobase/btr/btr0defragment.cc24
-rw-r--r--storage/innobase/btr/btr0pcur.cc39
-rw-r--r--storage/innobase/btr/btr0sea.cc22
-rw-r--r--storage/innobase/buf/buf0block_hint.cc59
-rw-r--r--storage/innobase/buf/buf0buddy.cc32
-rw-r--r--storage/innobase/buf/buf0buf.cc494
-rw-r--r--storage/innobase/buf/buf0dblwr.cc1579
-rw-r--r--storage/innobase/buf/buf0dump.cc57
-rw-r--r--storage/innobase/buf/buf0flu.cc2766
-rw-r--r--storage/innobase/buf/buf0lru.cc624
-rw-r--r--storage/innobase/buf/buf0rea.cc190
-rw-r--r--storage/innobase/dict/dict0boot.cc5
-rw-r--r--storage/innobase/dict/dict0crea.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc9
-rw-r--r--storage/innobase/dict/dict0load.cc8
-rw-r--r--storage/innobase/dict/dict0mem.cc57
-rw-r--r--storage/innobase/dict/dict0stats.cc210
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc2
-rw-r--r--storage/innobase/fil/fil0crypt.cc209
-rw-r--r--storage/innobase/fil/fil0fil.cc1823
-rw-r--r--storage/innobase/fsp/fsp0file.cc10
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc288
-rw-r--r--storage/innobase/fsp/fsp0space.cc2
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc68
-rw-r--r--storage/innobase/fts/fts0ast.cc8
-rw-r--r--storage/innobase/fts/fts0fts.cc8
-rw-r--r--storage/innobase/fts/fts0opt.cc20
-rw-r--r--storage/innobase/fts/fts0que.cc46
-rw-r--r--storage/innobase/gis/gis0sea.cc41
-rw-r--r--storage/innobase/handler/ha_innodb.cc214
-rw-r--r--storage/innobase/handler/ha_innodb.h3
-rw-r--r--storage/innobase/handler/handler0alter.cc111
-rw-r--r--storage/innobase/handler/i_s.cc88
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc176
-rw-r--r--storage/innobase/include/btr0btr.h12
-rw-r--r--storage/innobase/include/btr0btr.ic5
-rw-r--r--storage/innobase/include/btr0bulk.h9
-rw-r--r--storage/innobase/include/btr0cur.h33
-rw-r--r--storage/innobase/include/btr0defragment.h19
-rw-r--r--storage/innobase/include/btr0pcur.h11
-rw-r--r--storage/innobase/include/btr0sea.h2
-rw-r--r--storage/innobase/include/buf0block_hint.h76
-rw-r--r--storage/innobase/include/buf0buf.h249
-rw-r--r--storage/innobase/include/buf0buf.ic18
-rw-r--r--storage/innobase/include/buf0dblwr.h220
-rw-r--r--storage/innobase/include/buf0flu.h133
-rw-r--r--storage/innobase/include/buf0lru.h48
-rw-r--r--storage/innobase/include/buf0rea.h18
-rw-r--r--storage/innobase/include/buf0types.h15
-rw-r--r--storage/innobase/include/dict0defrag_bg.h4
-rw-r--r--storage/innobase/include/dict0dict.h2
-rw-r--r--storage/innobase/include/dict0dict.ic2
-rw-r--r--storage/innobase/include/dict0mem.h58
-rw-r--r--storage/innobase/include/dict0stats.ic7
-rw-r--r--storage/innobase/include/dict0stats_bg.h2
-rw-r--r--storage/innobase/include/fil0crypt.h4
-rw-r--r--storage/innobase/include/fil0fil.h690
-rw-r--r--storage/innobase/include/fsp0file.h14
-rw-r--r--storage/innobase/include/fsp0fsp.h24
-rw-r--r--storage/innobase/include/fsp0space.h6
-rw-r--r--storage/innobase/include/fsp0sysspace.h13
-rw-r--r--storage/innobase/include/fsp0types.h10
-rw-r--r--storage/innobase/include/fts0ast.h2
-rw-r--r--storage/innobase/include/fts0fts.h12
-rw-r--r--storage/innobase/include/fts0types.h2
-rw-r--r--storage/innobase/include/gis0rtree.h4
-rw-r--r--storage/innobase/include/gis0rtree.ic4
-rw-r--r--storage/innobase/include/gis0type.h12
-rw-r--r--storage/innobase/include/lock0lock.h5
-rw-r--r--storage/innobase/include/log0log.h150
-rw-r--r--storage/innobase/include/log0log.ic14
-rw-r--r--storage/innobase/include/log0recv.h25
-rw-r--r--storage/innobase/include/mtr0mtr.h6
-rw-r--r--storage/innobase/include/os0api.h48
-rw-r--r--storage/innobase/include/os0file.h337
-rw-r--r--storage/innobase/include/os0file.ic61
-rw-r--r--storage/innobase/include/os0thread.h37
-rw-r--r--storage/innobase/include/page0page.h4
-rw-r--r--storage/innobase/include/page0page.ic4
-rw-r--r--storage/innobase/include/que0que.h3
-rw-r--r--storage/innobase/include/srv0mon.h16
-rw-r--r--storage/innobase/include/srv0srv.h24
-rw-r--r--storage/innobase/include/srv0start.h5
-rw-r--r--storage/innobase/include/sync0arr.h9
-rw-r--r--storage/innobase/include/sync0debug.h6
-rw-r--r--storage/innobase/include/sync0rw.h6
-rw-r--r--storage/innobase/include/sync0sync.h15
-rw-r--r--storage/innobase/include/sync0types.h66
-rw-r--r--storage/innobase/include/trx0rseg.h10
-rw-r--r--storage/innobase/include/trx0rseg.ic6
-rw-r--r--storage/innobase/include/trx0sys.h10
-rw-r--r--storage/innobase/include/trx0undo.h2
-rw-r--r--storage/innobase/include/ut0mem.h5
-rw-r--r--storage/innobase/include/ut0mutex.h14
-rw-r--r--storage/innobase/include/ut0wqueue.h22
-rw-r--r--storage/innobase/lock/lock0lock.cc2
-rw-r--r--storage/innobase/lock/lock0wait.cc5
-rw-r--r--storage/innobase/log/log0log.cc728
-rw-r--r--storage/innobase/log/log0recv.cc297
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc257
-rw-r--r--storage/innobase/os/os0file.cc340
-rw-r--r--storage/innobase/os/os0thread.cc59
-rw-r--r--storage/innobase/row/row0import.cc27
-rw-r--r--storage/innobase/row/row0ins.cc57
-rw-r--r--storage/innobase/row/row0log.cc13
-rw-r--r--storage/innobase/row/row0merge.cc14
-rw-r--r--storage/innobase/row/row0mysql.cc10
-rw-r--r--storage/innobase/row/row0quiesce.cc17
-rw-r--r--storage/innobase/row/row0sel.cc35
-rw-r--r--storage/innobase/row/row0uins.cc10
-rw-r--r--storage/innobase/row/row0umod.cc58
-rw-r--r--storage/innobase/row/row0undo.cc14
-rw-r--r--storage/innobase/row/row0upd.cc2
-rw-r--r--storage/innobase/srv/srv0mon.cc97
-rw-r--r--storage/innobase/srv/srv0srv.cc104
-rw-r--r--storage/innobase/srv/srv0start.cc263
-rw-r--r--storage/innobase/sync/sync0arr.cc11
-rw-r--r--storage/innobase/sync/sync0debug.cc116
-rw-r--r--storage/innobase/sync/sync0sync.cc12
-rw-r--r--storage/innobase/trx/trx0i_s.cc24
-rw-r--r--storage/innobase/trx/trx0purge.cc11
-rw-r--r--storage/innobase/trx/trx0rec.cc29
-rw-r--r--storage/innobase/trx/trx0rseg.cc8
-rw-r--r--storage/innobase/trx/trx0sys.cc4
-rw-r--r--storage/innobase/trx/trx0undo.cc17
-rw-r--r--storage/innobase/ut/ut0wqueue.cc92
-rw-r--r--storage/maria/CMakeLists.txt3
-rw-r--r--storage/maria/ha_maria.cc13
-rw-r--r--storage/maria/ha_s3.cc37
-rw-r--r--storage/maria/ha_s3.h46
m---------storage/maria/libmarias30
-rw-r--r--storage/maria/ma_check.c3
-rw-r--r--storage/maria/ma_create.c1
-rw-r--r--storage/maria/ma_extra.c15
-rw-r--r--storage/maria/ma_open.c5
-rw-r--r--storage/maria/ma_pagecache.c11
-rw-r--r--storage/mroonga/vendor/groonga/CMakeLists.txt1
-rw-r--r--storage/mroonga/vendor/groonga/lib/CMakeLists.txt2
-rw-r--r--storage/myisam/ha_myisam.cc23
-rw-r--r--storage/rocksdb/build_rocksdb.cmake2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result15
-rw-r--r--storage/spider/spd_param.cc2
-rw-r--r--strings/ctype-mb.c4
-rw-r--r--strings/json_lib.c2
-rwxr-xr-xtests/drop_test.pl2
-rwxr-xr-xtests/fork2_test.pl2
-rwxr-xr-xtests/fork_big.pl2
-rw-r--r--tests/fork_big2.pl2
-rwxr-xr-xtests/index_corrupt.pl2
-rwxr-xr-xtests/insert_and_repair.pl2
-rwxr-xr-xtests/mail_to_db.pl2
-rw-r--r--tests/mysql_client_test.c155
-rwxr-xr-xtests/pmail.pl2
-rwxr-xr-xtests/rename_test.pl2
-rwxr-xr-xtests/test_delayed_insert.pl2
-rwxr-xr-xtests/truncate.pl2
-rw-r--r--tpool/tpool.h2
m---------wsrep-lib0
627 files changed, 34526 insertions, 13736 deletions
diff --git a/.gitignore b/.gitignore
index 7186bd12f08..d58dd2aa2b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -101,6 +101,7 @@ packaging/rpm-uln/mysql.10.0.11.spec
packaging/solaris/postinstall-solaris
extra/pcre2
plugin/auth_pam/auth_pam_tool
+plugin/auth_pam/config_auth_pam.h
plugin/aws_key_management/aws-sdk-cpp
plugin/aws_key_management/aws_sdk_cpp
plugin/aws_key_management/aws_sdk_cpp-prefix
diff --git a/appveyor.yml b/appveyor.yml
index 4a6a49fd8b5..4c83cb100b0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,7 +3,7 @@ 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
+ - cmake .. -DWITH_UNIT_TESTS=0 -DWITH_MARIABACKUP=0 -DMYSQL_MAINTAINER_MODE=ERR -DPLUGIN_ROCKSDB=NO -DPLUGIN_CONNECT=NO -DBISON_EXECUTABLE=C:\cygwin64\bin\bison
build:
project: win_build\MySQL.sln
@@ -18,4 +18,4 @@ test_script:
- 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
+image: Visual Studio 2019
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 63fec217433..666947d7b6c 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 */
@@ -1182,7 +1182,7 @@ static int check_version_match(void)
extract_variable_from_show(&ds_version, version_str))
{
print_error("Version check failed. Got the following error when calling "
- "the 'mysql_upgrade' command line client", &ds_version);
+ "the 'mysql' command line client", &ds_version);
dynstr_free(&ds_version);
return 1; /* Query failed */
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 4830a6c782b..4f5bb02d0c2 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -39,7 +39,7 @@
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.17"
+#define DUMP_VERSION "10.18"
#include <my_global.h>
#include <my_sys.h>
@@ -83,7 +83,8 @@
#define IGNORE_NONE 0x00 /* no ignore */
#define IGNORE_DATA 0x01 /* don't dump data for this table */
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
-#define IGNORE_S3_TABLE 0x04
+#define IGNORE_SEQUENCE_TABLE 0x04 /* catch the SEQUENCE*/
+#define IGNORE_S3_TABLE 0x08
/* Chars needed to store LONGLONG, excluding trailing '\0'. */
#define LONGLONG_LEN 20
@@ -2743,7 +2744,68 @@ static inline my_bool general_log_or_slow_log_tables(const char *db,
!my_strcasecmp(charset_info, table, "slow_log") ||
!my_strcasecmp(charset_info, table, "transaction_registry"));
}
+/*
+ get_sequence_structure-- retrievs sequence structure, prints out corresponding
+ CREATE statement
+ ARGS
+ seq - sequence name
+ db - db name
+*/
+
+static void get_sequence_structure(const char *seq, const char *db)
+{
+
+ char table_buff[NAME_LEN*2+3];
+ char *result_seq;
+ FILE *sql_file= md_result_file;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+
+ DBUG_ENTER("get_sequence_structure");
+ DBUG_PRINT("enter", ("db: %s sequence: %s", db, seq));
+
+ verbose_msg("-- Retrieving sequence structure for %s...\n", seq);
+
+ result_seq= quote_name(seq, table_buff, 1);
+ // Sequences as tables share same flags
+ if (!opt_no_create_info)
+ {
+ char buff[20+FN_REFLEN];
+ my_snprintf(buff, sizeof(buff), "SHOW CREATE SEQUENCE %s", result_seq);
+ if (mysql_query_with_error_report(mysql, &result, buff))
+ {
+ DBUG_VOID_RETURN;
+ }
+
+ print_comment(sql_file, 0,
+ "\n--\n-- Sequence structure for %s\n--\n\n",
+ fix_for_comment(result_seq));
+ if (opt_drop)
+ {
+ fprintf(sql_file, "DROP SEQUENCE IF EXISTS %s;\n", result_seq);
+ check_io(sql_file);
+ }
+
+ row= mysql_fetch_row(result);
+ fprintf(sql_file, "%s;\n", row[1]);
+ mysql_free_result(result);
+ // Restore next not cached value from sequence
+ my_snprintf(buff, sizeof(buff), "SELECT next_not_cached_value FROM %s", result_seq);
+ if (mysql_query_with_error_report(mysql, &result, buff))
+ {
+ DBUG_VOID_RETURN;
+ }
+ row= mysql_fetch_row(result);
+ if (row[0])
+ {
+ fprintf(sql_file, "SELECT SETVAL(%s, %s, 0);\n", result_seq, row[0]);
+ }
+ // Sequences will not use inserts, so no need for REPLACE and LOCKS
+ mysql_free_result(result);
+ }
+ DBUG_VOID_RETURN;
+}
/*
get_table_structure -- retrievs database structure, prints out corresponding
CREATE statement and fills out insert_pat if the table is the type we will
@@ -3746,6 +3808,14 @@ static void dump_table(char *table, char *db, const uchar *hash_key, size_t len)
DBUG_ENTER("dump_table");
/*
+ Check does table has a sequence structure and if has apply different sql queries
+ */
+ if (check_if_ignore_table(table, table_type) & IGNORE_SEQUENCE_TABLE)
+ {
+ get_sequence_structure(table, db);
+ DBUG_VOID_RETURN;
+ }
+ /*
Make sure you get the create table info before the following check for
--no-data flag below. Otherwise, the create table info won't be printed.
*/
@@ -5730,7 +5800,7 @@ char check_if_ignore_table(const char *table_name, char *table_type)
/* Check memory for quote_for_like() */
DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
my_snprintf(buff, sizeof(buff),
- "SELECT engine FROM INFORMATION_SCHEMA.TABLES "
+ "SELECT engine, table_type FROM INFORMATION_SCHEMA.TABLES "
"WHERE table_schema = DATABASE() AND table_name = %s",
quote_for_equal(table_name, show_name_buff));
if (mysql_query_with_error_report(mysql, &res, buff))
@@ -5770,6 +5840,8 @@ char check_if_ignore_table(const char *table_name, char *table_type)
strcmp(table_type,"MEMORY"))
result= IGNORE_INSERT_DELAYED;
}
+ if (!strcmp(row[1],"SEQUENCE"))
+ result|= IGNORE_SEQUENCE_TABLE;
if (!strcmp(table_type, "S3"))
result|= IGNORE_S3_TABLE;
diff --git a/cmake/check_linker_flag.cmake b/cmake/check_linker_flag.cmake
index ff4b91e89f6..1ea1772d79e 100644
--- a/cmake/check_linker_flag.cmake
+++ b/cmake/check_linker_flag.cmake
@@ -6,11 +6,11 @@ FUNCTION(MY_CHECK_AND_SET_LINKER_FLAG flag_to_set)
RETURN()
ENDIF()
STRING(REGEX REPLACE "[-,= +]" "_" result "HAVE_LINK_FLAG_${flag_to_set}")
- SET(SAVE_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
+ SET(SAVE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})
- SET(CMAKE_REQUIRED_LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS} ${flag_to_check})
+ SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${flag_to_check})
CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result})
- SET(CMAKE_REQUIRED_LINK_OPTIONS "${SAVE_CMAKE_REQUIRED_LINK_OPTIONS}")
+ SET(CMAKE_REQUIRED_LIBRARIES "${SAVE_CMAKE_REQUIRED_LIBRARIES}")
IF (${result})
FOREACH(linktype SHARED MODULE EXE)
IF(ARGN)
diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake
index 5ad636d0e6c..b94a880cf05 100644
--- a/cmake/jemalloc.cmake
+++ b/cmake/jemalloc.cmake
@@ -17,7 +17,7 @@ MACRO (CHECK_JEMALLOC)
IF(WITH_JEMALLOC STREQUAL "static")
SET(libname jemalloc_pic)
- SET(CMAKE_REQUIRED_LIBRARIES pthread dl m)
+ SET(CMAKE_REQUIRED_LIBRARIES pthread ${CMAKE_DL_LIBS} m)
SET(what bundled)
ELSE()
SET(libname jemalloc c)
diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake
index 92a5b9f564d..37f9cf196af 100644
--- a/cmake/libutils.cmake
+++ b/cmake/libutils.cmake
@@ -323,11 +323,14 @@ MACRO(MERGE_LIBRARIES)
ENDMACRO()
FUNCTION(GET_DEPENDEND_OS_LIBS target result)
- FOREACH(lib ${${target}_LIB_DEPENDS})
- IF(NOT TARGET ${lib})
- SET(ret ${ret} ${lib})
- ENDIF()
- ENDFOREACH()
+ GET_TARGET_PROPERTY(DEPS ${target} LINK_LIBRARIES)
+ IF(DEPS)
+ FOREACH(lib ${DEPS})
+ IF(NOT TARGET ${lib})
+ SET(ret ${ret} ${lib})
+ ENDIF()
+ ENDFOREACH()
+ ENDIF()
SET(${result} ${ret} PARENT_SCOPE)
ENDFUNCTION()
diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake
index 189253c5b23..29bd637250d 100644
--- a/cmake/os/Windows.cmake
+++ b/cmake/os/Windows.cmake
@@ -104,11 +104,15 @@ MACRO(ENABLE_SANITIZERS)
STRING(APPEND CMAKE_C_STANDARD_LIBRARIES " \"${${lib}_fullpath}\" ")
STRING(APPEND CMAKE_CXX_STANDARD_LIBRARIES " \"${${lib}_fullpath}\" ")
ENDFOREACH()
-
+ STRING(APPEND CMAKE_C_FLAGS ${SANITIZER_COMPILE_FLAGS})
+ STRING(APPEND CMAKE_CXX_FLAGS ${SANITIZER_COMPILE_FLAGS})
ENDMACRO()
IF(MSVC)
+ IF(MSVC_VERSION LESS 1920)
+ MESSAGE(FATAL_ERROR "Visual Studio q2019 or later is required")
+ ENDIF()
# Disable mingw based pkg-config found in Strawberry perl
SET(PKG_CONFIG_EXECUTABLE 0 CACHE INTERNAL "")
@@ -178,6 +182,9 @@ IF(MSVC)
-Wno-deprecated-register -Wno-missing-braces \
-Wno-unused-function -Wno-unused-local-typedef -msse4.2 "
)
+ IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
+ STRING(APPEND CLANG_CL_FLAGS "-mpclmul ")
+ ENDIF()
STRING(APPEND CMAKE_C_FLAGS " ${CLANG_CL_FLAGS} ${MSVC_CRT_TYPE}")
STRING(APPEND CMAKE_CXX_FLAGS " ${CLANG_CL_FLAGS} ${MSVC_CRT_TYPE}")
ENDIF()
diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
index 7143fce9e09..5f54d77752c 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
@@ -126,7 +126,7 @@ MACRO (MYSQL_CHECK_SSL)
SET(SSL_LIBRARIES ${SSL_LIBRARIES} ${LIBSOCKET})
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
- SET(SSL_LIBRARIES ${SSL_LIBRARIES} ${LIBDL})
+ SET(SSL_LIBRARIES ${SSL_LIBRARIES} ${CMAKE_DL_LIBS})
ENDIF()
MESSAGE_ONCE(OPENSSL_INCLUDE_DIR "OPENSSL_INCLUDE_DIR = ${OPENSSL_INCLUDE_DIR}")
diff --git a/configure.cmake b/configure.cmake
index 8533b8ee0b2..64be91606ae 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -130,7 +130,6 @@ IF(UNIX)
MY_SEARCH_LIBS(bind "bind;socket" LIBBIND)
MY_SEARCH_LIBS(crypt crypt LIBCRYPT)
MY_SEARCH_LIBS(setsockopt socket LIBSOCKET)
- MY_SEARCH_LIBS(dlopen dl LIBDL)
MY_SEARCH_LIBS(sched_yield rt LIBRT)
IF(NOT LIBRT)
MY_SEARCH_LIBS(clock_gettime rt LIBRT)
@@ -138,7 +137,7 @@ IF(UNIX)
FIND_PACKAGE(Threads)
SET(CMAKE_REQUIRED_LIBRARIES
- ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO})
+ ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO})
# Need explicit pthread for gcc -fsanitize=address
IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=")
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} pthread)
diff --git a/debian/additions/mariadb-report b/debian/additions/mariadb-report
index 206aaefb2f8..5c9761e0710 100755
--- a/debian/additions/mariadb-report
+++ b/debian/additions/mariadb-report
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/perl
# mariadb-report v4.0 Oct 23 2015
# renamed to from mysqlreport in 2020
diff --git a/debian/mariadb-plugin-columnstore.install b/debian/mariadb-plugin-columnstore.install
index 3b4c9619dc6..f519fa2a37e 100644
--- a/debian/mariadb-plugin-columnstore.install
+++ b/debian/mariadb-plugin-columnstore.install
@@ -55,6 +55,7 @@ usr/bin/mariadb-columnstore-start.sh
usr/bin/mariadb-columnstore-stop.sh
usr/bin/mariadb-command-line.sh
usr/bin/master-rep-columnstore.sh
+usr/bin/mcs-savebrm.py
usr/bin/mcs-loadbrm.py
usr/bin/mcs-stop-controllernode.sh
usr/bin/mcsGetConfig
diff --git a/debian/mariadb-server-10.6.install b/debian/mariadb-server-10.6.install
index 883c0b9f0aa..f0c644482cd 100644
--- a/debian/mariadb-server-10.6.install
+++ b/debian/mariadb-server-10.6.install
@@ -61,6 +61,7 @@ usr/lib/mysql/plugin/query_response_time.so
usr/lib/mysql/plugin/server_audit.so
usr/lib/mysql/plugin/simple_password_check.so
usr/lib/mysql/plugin/sql_errlog.so
+usr/lib/mysql/plugin/type_mysql_json.so
usr/lib/mysql/plugin/wsrep_info.so
usr/share/doc/mariadb-server-10.6/mariadbd.sym.gz
usr/share/man/man1/aria_chk.1
diff --git a/debian/mariadb-server-10.6.mysql-server.logrotate b/debian/mariadb-server-10.6.mysql-server.logrotate
index eed6fc5e88d..4111a276dc3 100644
--- a/debian/mariadb-server-10.6.mysql-server.logrotate
+++ b/debian/mariadb-server-10.6.mysql-server.logrotate
@@ -11,7 +11,7 @@
sharedscripts
postrotate
test -x /usr/bin/mysqladmin || exit 0
- if [ -f `my_print_defaults --mariadbd | grep -oP "pid-file=\K[^$]+"` ]; then
+ if [ -f `my_print_defaults --mysqld | grep -oP "pid-file=\K[^$]+"` ]; then
# If this fails, check debian.conf!
mysqladmin --defaults-file=/etc/mysql/debian.cnf --local flush-error-log \
flush-engine-log flush-general-log flush-slow-log
diff --git a/debian/mariadb-server-10.6.postinst b/debian/mariadb-server-10.6.postinst
index 6decee78766..c29b3532cb2 100644
--- a/debian/mariadb-server-10.6.postinst
+++ b/debian/mariadb-server-10.6.postinst
@@ -103,6 +103,19 @@ EOF
rmdir $mysql_upgradedir 2>/dev/null || true
done
+ # Upgrading from mysql.com needs might have the root user as auth_socket.
+ # auto.cnf is a sign of a mysql install, that doesn't exist in mariadb.
+ # We use lsof to protect against concurrent access by mysqld (mariadb has
+ # its own projection). We make sure we're not doing this on a MySQL-8.0
+ # directory.
+ # This direct update is needed to enable an authentication mechanism to
+ # perform mariadb-upgrade, (MDEV-22678). To keep the impact minimal, we
+ # skip innodb and set key-buffer-size to 0 as it isn't reused.
+ if [ -f "$mysql_datadir"/auto.cnf ] && [ -f "$mysql_datadir"/mysql/user.MYD ] &&
+ [ ! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null ] && [ ! -f "$mysql_datadir"/undo_001 ]; then
+ echo "UPDATE mysql.user SET plugin='unix_socket' WHERE plugin='auth_socket';" |
+ /usr/sbin/mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null
+ fi
# Ensure the existence and right permissions for the database and
# log files. Use mkdir option 'Z' to create with correct SELinux context.
diff --git a/debian/mariadb-test.install b/debian/mariadb-test.install
index 767ec1ce587..56947ac78ef 100644
--- a/debian/mariadb-test.install
+++ b/debian/mariadb-test.install
@@ -8,6 +8,7 @@ usr/lib/*/libmariadb3/plugin/qa_auth_interface.so
usr/lib/mysql/plugin/adt_null.so
usr/lib/mysql/plugin/auth_0x0100.so
usr/lib/mysql/plugin/auth_test_plugin.so
+usr/lib/mysql/plugin/test_sql_service.so
usr/lib/mysql/plugin/daemon_example.ini
usr/lib/mysql/plugin/debug_key_management.so
usr/lib/mysql/plugin/dialog_examples.so
diff --git a/debian/rules b/debian/rules
index aa5c7b1b6e0..686c1c5e3dd 100755
--- a/debian/rules
+++ b/debian/rules
@@ -165,6 +165,7 @@ endif
# load from the libmariadb path as well
ln -s ../../../mysql/plugin/auth_test_plugin.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/auth_test_plugin.so
ln -s ../../../mysql/plugin/qa_auth_interface.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/qa_auth_interface.so
+ ln -s ../../../mysql/plugin/test_sql_service.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/test_sql_service.so
# Move test plugins that are only needed by the client to the libmariadb path
mv -v $(TMP)/usr/lib/mysql/plugin/qa_auth_client.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/
diff --git a/extra/aws_sdk/CMakeLists.txt b/extra/aws_sdk/CMakeLists.txt
index 85a196dccce..7c4b8d8195c 100644
--- a/extra/aws_sdk/CMakeLists.txt
+++ b/extra/aws_sdk/CMakeLists.txt
@@ -34,7 +34,7 @@ ENDFOREACH()
IF(CMAKE_VERSION LESS "3.0")
SET(GIT_TAG "1.0.8")
ELSE()
- SET(GIT_TAG "1.2.11")
+ SET(GIT_TAG "1.8.29")
ENDIF()
IF(MSVC_CRT_TYPE MATCHES "/MD")
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 4ad14dc4740..c841725f552 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -961,7 +961,7 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
data_threads[i].n_thread = i + 1;
data_threads[i].count = &count;
data_threads[i].count_mutex = &count_mutex;
- os_thread_create(func, data_threads + i, &data_threads[i].id);
+ data_threads[i].id = os_thread_create(func, data_threads + i);
}
/* Wait for threads to exit */
@@ -1382,7 +1382,7 @@ out:
void backup_fix_ddl(void);
-static lsn_t get_current_lsn(MYSQL *connection)
+lsn_t get_current_lsn(MYSQL *connection)
{
static const char lsn_prefix[] = "\nLog sequence number ";
lsn_t lsn = 0;
diff --git a/extra/mariabackup/backup_copy.h b/extra/mariabackup/backup_copy.h
index fbc09eaded3..7c886719f37 100644
--- a/extra/mariabackup/backup_copy.h
+++ b/extra/mariabackup/backup_copy.h
@@ -3,6 +3,7 @@
#define XTRABACKUP_BACKUP_COPY_H
#include <my_global.h>
+#include <mysql.h>
#include "datasink.h"
/* special files */
@@ -48,4 +49,7 @@ is_path_separator(char);
bool
directory_exists(const char *dir, bool create);
+lsn_t
+get_current_lsn(MYSQL *connection);
+
#endif
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index 83e877ea9bb..28aed958c73 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -75,7 +75,6 @@ bool have_multi_threaded_slave = false;
bool have_gtid_slave = false;
/* Kill long selects */
-os_thread_id_t kill_query_thread_id;
os_event_t kill_query_thread_started;
os_event_t kill_query_thread_stopped;
os_event_t kill_query_thread_stop;
@@ -856,7 +855,7 @@ start_query_killer()
kill_query_thread_started = os_event_create(0);
kill_query_thread_stopped = os_event_create(0);
- os_thread_create(kill_query_thread, NULL, &kill_query_thread_id);
+ os_thread_create(kill_query_thread);
os_event_wait(kill_query_thread_started);
}
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index 8f06005a9e4..4f9e493b347 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -93,8 +93,6 @@ xb_fil_node_close_file(
mutex_enter(&fil_system.mutex);
ut_ad(node);
- ut_a(node->n_pending == 0);
- ut_a(node->n_pending_flushes == 0);
ut_a(!node->being_extended);
if (!node->is_open()) {
@@ -108,20 +106,10 @@ xb_fil_node_close_file(
ut_a(ret);
node->handle = OS_FILE_CLOSED;
+ mutex_exit(&fil_system.mutex);
ut_a(fil_system.n_open > 0);
fil_system.n_open--;
-
- if (node->space->purpose == FIL_TYPE_TABLESPACE &&
- fil_is_user_tablespace_id(node->space->id)) {
-
- ut_a(UT_LIST_GET_LEN(fil_system.LRU) > 0);
-
- /* The node is in the LRU list, remove it */
- UT_LIST_REMOVE(fil_system.LRU, node);
- }
-
- mutex_exit(&fil_system.mutex);
}
/************************************************************************
@@ -180,18 +168,8 @@ xb_fil_cur_open(
return(XB_FIL_CUR_SKIP);
}
- mutex_enter(&fil_system.mutex);
fil_system.n_open++;
-
- if (node->space->purpose == FIL_TYPE_TABLESPACE &&
- fil_is_user_tablespace_id(node->space->id)) {
-
- /* Put the node to the LRU list */
- UT_LIST_ADD_FIRST(fil_system.LRU, node);
- }
-
- mutex_exit(&fil_system.mutex);
}
ut_ad(node->is_open());
@@ -427,7 +405,7 @@ xb_fil_cur_read(
retry_count = 10;
ret = XB_FIL_CUR_SUCCESS;
- fil_space_t *space = fil_space_acquire_for_io(cursor->space_id);
+ fil_space_t *space = fil_space_t::get(cursor->space_id);
if (!space) {
return XB_FIL_CUR_ERROR;
@@ -476,7 +454,7 @@ read_retry:
posix_fadvise(cursor->file, offset, to_read, POSIX_FADV_DONTNEED);
func_exit:
- space->release_for_io();
+ space->release();
return(ret);
}
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 6442139f17d..097f2caa262 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -503,7 +503,7 @@ static os_event_t dbug_start_query_thread(
par->expect_errno = expected_errno;
par->done_event = os_event_create(0);
par->con = xb_mysql_connect();
- os_thread_create(dbug_execute_in_new_connection, par, 0);
+ os_thread_create(dbug_execute_in_new_connection, par);
if (!wait_state)
return par->done_event;
@@ -1251,7 +1251,7 @@ struct my_option xb_server_options[] =
"Data file autoextend increment in megabytes",
(G_PTR*) &sys_tablespace_auto_extend_increment,
(G_PTR*) &sys_tablespace_auto_extend_increment,
- 0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
+ 0, GET_UINT, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
{"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
"Path to individual files and their sizes.", &innobase_data_file_path,
&innobase_data_file_path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -2283,7 +2283,7 @@ check_if_skip_database(
if (databases_exclude_hash.array &&
find_filter_in_hashtable(name, &databases_exclude_hash,
&database) &&
- !database->has_tables) {
+ (!database->has_tables || !databases_include_hash.array)) {
/* Database is found and there are no tables specified,
skip entire db. */
return DATABASE_SKIP;
@@ -2453,17 +2453,24 @@ xb_get_copy_action(const char *dflt)
return(action);
}
-/* TODO: We may tune the behavior (e.g. by fil_aio)*/
-static
-my_bool
-xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=0, ulonglong max_size=ULLONG_MAX)
+/** Copy innodb data file to the specified destination.
+
+@param[in] node file node of a tablespace
+@param[in] thread_n thread id, used in the text of diagnostic messages
+@param[in] dest_name destination file name
+@param[in] write_filter write filter to copy data, can be pass-through filter
+for full backup, pages filter for incremental backup, etc.
+
+@return FALSE on success and TRUE on error */
+static my_bool xtrabackup_copy_datafile(fil_node_t *node, uint thread_n,
+ const char *dest_name,
+ const xb_write_filt_t &write_filter)
{
char dst_name[FN_REFLEN];
ds_file_t *dstfile = NULL;
xb_fil_cur_t cursor;
xb_fil_cur_result_t res;
- xb_write_filt_t *write_filter = NULL;
xb_write_filt_ctxt_t write_filt_ctxt;
const char *action;
xb_read_filt_t *read_filter;
@@ -2487,6 +2494,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
return(FALSE);
}
+ memset(&write_filt_ctxt, 0, sizeof(xb_write_filt_ctxt_t));
+
bool was_dropped;
pthread_mutex_lock(&backup_mutex);
was_dropped = (ddl_tracker.drops.find(node->space->id) != ddl_tracker.drops.end());
@@ -2507,7 +2516,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
read_filter = &rf_bitmap;
}
- res = xb_fil_cur_open(&cursor, read_filter, node, thread_n,max_size);
+ res = xb_fil_cur_open(&cursor, read_filter, node, thread_n, ULLONG_MAX);
if (res == XB_FIL_CUR_SKIP) {
goto skip;
} else if (res == XB_FIL_CUR_ERROR) {
@@ -2518,18 +2527,10 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
sizeof dst_name - 1);
dst_name[sizeof dst_name - 1] = '\0';
- /* Setup the page write filter */
- if (xtrabackup_incremental) {
- write_filter = &wf_incremental;
- } else {
- write_filter = &wf_write_through;
- }
-
- memset(&write_filt_ctxt, 0, sizeof(xb_write_filt_ctxt_t));
- ut_a(write_filter->process != NULL);
+ ut_a(write_filter.process != NULL);
- if (write_filter->init != NULL &&
- !write_filter->init(&write_filt_ctxt, dst_name, &cursor)) {
+ if (write_filter.init != NULL &&
+ !write_filter.init(&write_filt_ctxt, dst_name, &cursor)) {
msg (thread_n, "mariabackup: error: failed to initialize page write filter.");
goto error;
}
@@ -2550,7 +2551,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
/* The main copy loop */
while ((res = xb_fil_cur_read(&cursor)) == XB_FIL_CUR_SUCCESS) {
- if (!write_filter->process(&write_filt_ctxt, dstfile)) {
+ if (!write_filter.process(&write_filt_ctxt, dstfile)) {
goto error;
}
}
@@ -2559,8 +2560,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
goto error;
}
- if (write_filter->finalize
- && !write_filter->finalize(&write_filt_ctxt, dstfile)) {
+ if (write_filter.finalize
+ && !write_filter.finalize(&write_filt_ctxt, dstfile)) {
goto error;
}
@@ -2574,8 +2575,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
if (ds_close(dstfile)) {
rc = TRUE;
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);
}
return(rc);
@@ -2584,8 +2585,8 @@ error:
if (dstfile != NULL) {
ds_close(dstfile);
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);;
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);;
}
msg(thread_n, "mariabackup: xtrabackup_copy_datafile() failed.");
return(TRUE); /*ERROR*/
@@ -2595,8 +2596,8 @@ skip:
if (dstfile != NULL) {
ds_close(dstfile);
}
- if (write_filter && write_filter->deinit) {
- write_filter->deinit(&write_filt_ctxt);
+ if (write_filter.deinit) {
+ write_filter.deinit(&write_filt_ctxt);
}
msg(thread_n,"Warning: We assume the table was dropped during xtrabackup execution and ignore the tablespace %s", node_name);
return(FALSE);
@@ -2642,7 +2643,7 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
/* We got a full log block. */
scanned_lsn += data_len;
} else if (data_len >= log_sys.trailer_offset()
- || data_len <= LOG_BLOCK_HDR_SIZE) {
+ || data_len < LOG_BLOCK_HDR_SIZE) {
/* We got a garbage block (abrupt end of the log). */
msg(0,"garbage block: " LSN_PF ",%zu",scanned_lsn, data_len);
break;
@@ -2703,7 +2704,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
xtrabackup_io_throttling();
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
lsn_t lsn= start_lsn;
for (int retries= 0; retries < 100; retries++) {
if (log_sys.log.read_log_seg(&lsn, end_lsn)
@@ -2727,7 +2728,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
mutex_exit(&recv_sys.mutex);
}
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (!start_lsn) {
const char *reason = recv_sys.found_corrupt_log
@@ -2787,10 +2788,10 @@ static os_thread_ret_t DECLARE_THREAD(log_copying_thread)(void*)
break;
}
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
bool completed = metadata_to_lsn
&& metadata_to_lsn <= log_copy_scanned_lsn;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (completed) {
break;
}
@@ -2859,8 +2860,14 @@ static void dbug_mariabackup_event(const char *event,const char *key)
}
#define DBUG_MARIABACKUP_EVENT(A, B) DBUG_EXECUTE_IF("mariabackup_events", dbug_mariabackup_event(A,B););
+#define DBUG_MB_INJECT_CODE(EVENT, KEY, CODE) \
+ DBUG_EXECUTE_IF("mariabackup_inject_code", {\
+ char *env = getenv(EVENT); \
+ if (env && !strcmp(env, KEY)) { CODE } \
+ })
#else
#define DBUG_MARIABACKUP_EVENT(A,B)
+#define DBUG_MB_INJECT_CODE(EVENT, KEY, CODE)
#endif
/**************************************************************************
@@ -2885,10 +2892,12 @@ DECLARE_THREAD(data_copy_thread_func)(
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
+ DBUG_MB_INJECT_CODE("wait_innodb_redo_before_copy", node->space->name,
+ backup_wait_for_lsn(get_current_lsn(mysql_connection)););
/* copy the datafile */
- if(xtrabackup_copy_datafile(node, num)) {
+ if (xtrabackup_copy_datafile(node, num, NULL,
+ xtrabackup_incremental ? wf_incremental : wf_write_through))
die("failed to copy datafile.");
- }
DBUG_MARIABACKUP_EVENT("after_copy", node->space->name);
@@ -3003,6 +3012,8 @@ void
xb_fil_io_init()
{
fil_system.create(srv_file_per_table ? 50000 : 5000);
+ fil_system.freeze_space_list = 1;
+ fil_system.space_id_reuse_warned = true;
}
static
@@ -3078,24 +3089,16 @@ xb_load_single_table_tablespace(
bool is_empty_file = file->exists() && file->is_empty_file();
if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) {
- os_offset_t node_size = os_file_get_size(file->handle());
- os_offset_t n_pages;
-
- ut_a(node_size != (os_offset_t) -1);
-
- n_pages = node_size / fil_space_t::physical_size(file->flags());
-
- space = fil_space_create(
+ space = fil_space_t::create(
name, file->space_id(), file->flags(),
FIL_TYPE_TABLESPACE, NULL/* TODO: crypt_data */);
ut_a(space != NULL);
- space->add(file->filepath(), OS_FILE_CLOSED, ulint(n_pages),
- false, false);
- /* by opening the tablespace we forcing node and space objects
- in the cache to be populated with fields from space header */
- space->open();
+ space->add(file->filepath(), file->detach(), 0, false, false);
+ mutex_enter(&fil_system.mutex);
+ space->read_page0();
+ mutex_exit(&fil_system.mutex);
if (srv_operation == SRV_OPERATION_RESTORE_DELTA
|| xb_close_files) {
@@ -3397,30 +3400,11 @@ xb_load_tablespaces()
return(DB_SUCCESS);
}
-/************************************************************************
-Initialize the tablespace memory cache and populate it by scanning for and
-opening data files.
-@returns DB_SUCCESS or error code.*/
-static
-dberr_t
-xb_data_files_init()
+/** Destroy the tablespace memory cache. */
+static void xb_data_files_close()
{
- xb_fil_io_init();
-
- return(xb_load_tablespaces());
-}
-
-/************************************************************************
-Destroy the tablespace memory cache. */
-static
-void
-xb_data_files_close()
-{
- ut_ad(!os_thread_count);
- fil_close_all_files();
- if (buf_dblwr) {
- buf_dblwr_free();
- }
+ fil_space_t::close_all();
+ buf_dblwr.close();
}
/***********************************************************************
@@ -3865,7 +3849,7 @@ static bool xtrabackup_backup_low()
{
ulint max_cp_field;
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (recv_find_max_checkpoint(&max_cp_field) == DB_SUCCESS
&& log_sys.log.format != 0) {
@@ -3882,7 +3866,7 @@ static bool xtrabackup_backup_low()
} else {
msg("Error: recv_find_max_checkpoint() failed.");
}
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
}
stop_backup_threads();
@@ -4009,7 +3993,6 @@ fail:
}
srv_thread_pool_init();
sync_check_init();
- ut_d(sync_check_enable());
/* Reset the system variables in the recovery module. */
trx_pool_init();
recv_sys.create();
@@ -4052,26 +4035,23 @@ fail:
/* definition from recv_recovery_from_checkpoint_start() */
ulint max_cp_field;
- /* start back ground thread to copy newer log */
- os_thread_id_t log_copying_thread_id;
-
/* get current checkpoint_lsn */
/* Look for the latest checkpoint from any of the log groups */
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
reread_log_header:
dberr_t err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
msg("Error: cannot read redo log header");
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
goto fail;
}
if (log_sys.log.format == 0) {
msg("Error: cannot process redo log before MariaDB 10.2.2");
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
goto fail;
}
@@ -4088,7 +4068,7 @@ reread_log_header:
!= mach_read_from_8(buf + LOG_CHECKPOINT_OFFSET))
goto reread_log_header;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
xtrabackup_init_datasinks();
@@ -4144,14 +4124,11 @@ reread_log_header:
log_copying_running = true;
/* start io throttle */
if(xtrabackup_throttle) {
- os_thread_id_t io_watching_thread_id;
-
io_ticket = xtrabackup_throttle;
wait_throttle = os_event_create(0);
io_watching_thread_running = true;
- os_thread_create(io_watching_thread, NULL,
- &io_watching_thread_id);
+ os_thread_create(io_watching_thread);
}
/* Populate fil_system with tablespaces to copy */
@@ -4174,7 +4151,7 @@ fail_before_log_copying_thread_start:
DBUG_MARIABACKUP_EVENT("before_innodb_log_copy_thread_started",0);
log_copying_stop = os_event_create(0);
- os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
+ os_thread_create(log_copying_thread);
/* FLUSH CHANGED_PAGE_BITMAPS call */
if (!flush_changed_page_bitmaps()) {
@@ -4216,8 +4193,8 @@ fail_before_log_copying_thread_start:
data_threads[i].num = i+1;
data_threads[i].count = &count;
data_threads[i].count_mutex = &count_mutex;
- os_thread_create(data_copy_thread_func, data_threads + i,
- &data_threads[i].id);
+ data_threads[i].id = os_thread_create(data_copy_thread_func,
+ data_threads + i);
}
/* Wait for threads to exit */
@@ -4430,7 +4407,7 @@ void backup_fix_ddl(void)
continue;
std::string dest_name(node->space->name);
dest_name.append(".new");
- xtrabackup_copy_datafile(node, 0, dest_name.c_str()/*, do_full_copy ? ULONGLONG_MAX:UNIV_PAGE_SIZE */);
+ xtrabackup_copy_datafile(node, 0, dest_name.c_str(), wf_write_through);
}
datafiles_iter_free(it);
@@ -4611,7 +4588,23 @@ xb_delta_open_matching_space(
return file;
}
- log_mutex_enter();
+ if (!info.space_id && fil_system.sys_space) {
+ fil_node_t *node
+ = UT_LIST_GET_FIRST(fil_system.sys_space->chain);
+ for (; node; node = UT_LIST_GET_NEXT(chain, node)) {
+ if (!strcmp(node->name, real_name)) {
+ break;
+ }
+ }
+ if (node && node->handle != OS_FILE_CLOSED) {
+ *success = true;
+ return node->handle;
+ }
+ msg("mariabackup: Cannot find file %s\n", real_name);
+ return OS_FILE_CLOSED;
+ }
+
+ mysql_mutex_lock(&log_sys.mutex);
if (!fil_is_user_tablespace_id(info.space_id)) {
found:
/* open the file and return its handle */
@@ -4624,7 +4617,7 @@ found:
msg("mariabackup: Cannot open file %s\n", real_name);
}
exit:
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return file;
}
@@ -4708,8 +4701,8 @@ exit:
ut_ad(fil_space_t::zip_size(flags) == info.zip_size);
ut_ad(fil_space_t::physical_size(flags) == info.page_size);
- if (fil_space_create(dest_space_name, info.space_id, flags,
- FIL_TYPE_TABLESPACE, 0)) {
+ if (fil_space_t::create(dest_space_name, info.space_id, flags,
+ FIL_TYPE_TABLESPACE, 0)) {
*success = xb_space_create_file(real_name, info.space_id,
flags, &file);
} else {
@@ -4902,7 +4895,7 @@ xtrabackup_apply_delta(
space->chain);
bool fail = !strcmp(n->name, dst_path)
&& !fil_space_extend(
- space, (ulint)n_pages);
+ space, uint32_t(n_pages));
if (fail) goto error;
}
}
@@ -4929,7 +4922,7 @@ xtrabackup_apply_delta(
os_file_close(src_file);
os_file_delete(0,src_path);
}
- if (dst_file != OS_FILE_CLOSED)
+ if (dst_file != OS_FILE_CLOSED && info.space_id)
os_file_close(dst_file);
return TRUE;
@@ -4937,7 +4930,7 @@ error:
aligned_free(incremental_buffer);
if (src_file != OS_FILE_CLOSED)
os_file_close(src_file);
- if (dst_file != OS_FILE_CLOSED)
+ if (dst_file != OS_FILE_CLOSED && info.space_id)
os_file_close(dst_file);
msg("Error: xtrabackup_apply_delta(): "
"failed to apply %s to %s.\n", src_path, dst_path);
@@ -4987,22 +4980,66 @@ static void rename_force(const char *from, const char *to) {
rename_file(from,to);
}
-/* During prepare phase, rename ".new" files , that were created in backup_fix_ddl(),
- to ".ibd".*/
-static ibool prepare_handle_new_files(
- const char* data_home_dir, /*!<in: path to datadir */
- const char* db_name, /*!<in: database name */
- const char* file_name, /*!<in: file name with suffix */
- void *)
-{
+/** During prepare phase, rename ".new" files, that were created in
+backup_fix_ddl() and backup_optimized_ddl_op(), to ".ibd". In the case of
+incremental backup, i.e. of arg argument is set, move ".new" files to
+destination directory and rename them to ".ibd", remove existing ".ibd.delta"
+and ".idb.meta" files in incremental directory to avoid applying delta to
+".ibd" file.
+
+@param[in] data_home_dir path to datadir
+@param[in] db_name database name
+@param[in] file_name file name with suffix
+@param[in] arg destination path, used in incremental backup to notify, that
+*.new file must be moved to destibation directory
+
+@return true */
+static ibool prepare_handle_new_files(const char *data_home_dir,
+ const char *db_name,
+ const char *file_name, void *arg)
+{
+ const char *dest_dir = static_cast<const char *>(arg);
std::string src_path = std::string(data_home_dir) + '/' + std::string(db_name) + '/' + file_name;
- std::string dest_path = src_path;
+ /* Copy "*.new" files from incremental to base dir for incremental backup */
+ std::string dest_path=
+ dest_dir ? std::string(dest_dir) + '/' + std::string(db_name) +
+ '/' + file_name : src_path;
size_t index = dest_path.find(".new");
DBUG_ASSERT(index != std::string::npos);
- dest_path.replace(index, 4, ".ibd");
+ dest_path.replace(index, strlen(".ibd"), ".ibd");
rename_force(src_path.c_str(),dest_path.c_str());
+
+ if (dest_dir) {
+ /* remove delta and meta files to avoid delta applying for new file */
+ index = src_path.find(".new");
+ DBUG_ASSERT(index != std::string::npos);
+ src_path.replace(index, std::string::npos, ".ibd.delta");
+ if (access(src_path.c_str(), R_OK) == 0) {
+ msg("Removing %s", src_path.c_str());
+ if (my_delete(src_path.c_str(), MYF(MY_WME)))
+ die("Can't remove %s, errno %d", src_path.c_str(), errno);
+ }
+ src_path.replace(index, std::string::npos, ".ibd.meta");
+ if (access(src_path.c_str(), R_OK) == 0) {
+ msg("Removing %s", src_path.c_str());
+ if (my_delete(src_path.c_str(), MYF(MY_WME)))
+ die("Can't remove %s, errno %d", src_path.c_str(), errno);
+ }
+
+ /* add table name to the container to avoid it's deletion at the end of
+ prepare */
+ std::string table_name = std::string(db_name) + '/'
+ + std::string(file_name, file_name + strlen(file_name) - strlen(".new"));
+ xb_filter_entry_t *table = static_cast<xb_filter_entry_t *>
+ (malloc(sizeof(xb_filter_entry_t) + table_name.size() + 1));
+ table->name = ((char*)table) + sizeof(xb_filter_entry_t);
+ strcpy(table->name, table_name.c_str());
+ HASH_INSERT(xb_filter_entry_t, name_hash, &inc_dir_tables_hash,
+ ut_fold_string(table->name), table);
+ }
+
return TRUE;
}
@@ -5039,17 +5076,18 @@ rm_if_not_found(
return(TRUE);
}
-/************************************************************************
-Function enumerates files in datadir (provided by path) which are matched
+/** Function enumerates files in datadir (provided by path) which are matched
by provided suffix. For each entry callback is called.
+
+@param[in] path datadir path
+@param[in] suffix suffix to match against
+@param[in] func callback
+@param[in] func_arg arguments for the above callback
+
@return FALSE if callback for some entry returned FALSE */
-static
-ibool
-xb_process_datadir(
- const char* path, /*!<in: datadir path */
- const char* suffix, /*!<in: suffix to match
- against */
- handle_datadir_entry_func_t func) /*!<in: callback */
+static ibool xb_process_datadir(const char *path, const char *suffix,
+ handle_datadir_entry_func_t func,
+ void *func_arg = NULL)
{
ulint ret;
char dbpath[OS_FILE_MAX_PATH+2];
@@ -5084,7 +5122,7 @@ xb_process_datadir(
suffix)) {
if (!func(
path, NULL,
- fileinfo.name, NULL))
+ fileinfo.name, func_arg))
{
os_file_closedir(dbdir);
return(FALSE);
@@ -5148,7 +5186,7 @@ next_file_item_1:
if (!func(
path,
dbinfo.name,
- fileinfo.name, NULL))
+ fileinfo.name, func_arg))
{
os_file_closedir(dbdir);
os_file_closedir(dir);
@@ -5308,6 +5346,10 @@ static bool xtrabackup_prepare_func(char** argv)
fil_path_to_mysql_datadir = ".";
+ ut_ad(xtrabackup_incremental == xtrabackup_incremental_dir);
+ if (xtrabackup_incremental)
+ inc_dir_tables_hash.create(1000);
+
/* Fix DDL for prepare. Process .del,.ren, and .new files.
The order in which files are processed, is important
(see MDEV-18185, MDEV-18201)
@@ -5319,6 +5361,8 @@ static bool xtrabackup_prepare_func(char** argv)
if (xtrabackup_incremental_dir) {
xb_process_datadir(xtrabackup_incremental_dir, ".new.meta", prepare_handle_new_files);
xb_process_datadir(xtrabackup_incremental_dir, ".new.delta", prepare_handle_new_files);
+ xb_process_datadir(xtrabackup_incremental_dir, ".new",
+ prepare_handle_new_files, (void *)".");
}
else {
xb_process_datadir(".", ".new", prepare_handle_new_files);
@@ -5383,7 +5427,6 @@ static bool xtrabackup_prepare_func(char** argv)
}
sync_check_init();
- ut_d(sync_check_enable());
recv_sys.create();
log_sys.create();
recv_sys.recovery_on = true;
@@ -5392,16 +5435,15 @@ static bool xtrabackup_prepare_func(char** argv)
srv_allow_writes_event = os_event_create(0);
os_event_set(srv_allow_writes_event);
#endif
- dberr_t err = xb_data_files_init();
- if (err != DB_SUCCESS) {
+ xb_fil_io_init();
+ if (dberr_t err = xb_load_tablespaces()) {
msg("mariabackup: error: xb_data_files_init() failed "
"with error %s\n", ut_strerr(err));
goto error_cleanup;
}
- inc_dir_tables_hash.create(1000);
-
- ok = xtrabackup_apply_deltas();
+ ok = fil_system.sys_space->open(false)
+ && xtrabackup_apply_deltas();
xb_data_files_close();
@@ -5431,6 +5473,8 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup;
}
+ fil_system.freeze_space_list = 0;
+
/* increase IO threads */
if (srv_n_file_io_threads < 10) {
srv_n_read_io_threads = 4;
@@ -5452,6 +5496,8 @@ static bool xtrabackup_prepare_func(char** argv)
goto error_cleanup;
}
+ ut_ad(!fil_system.freeze_space_list);
+
if (ok) {
msg("Last binlog file %s, position %lld",
trx_sys.recovered_binlog_filename,
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 59ac7814aee..5fa8f28ff7a 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -1175,7 +1175,7 @@ extern struct charset_info_st my_charset_utf8mb3_general_nopad_ci;
extern struct charset_info_st my_charset_utf8mb3_general_mysql500_ci;
extern struct charset_info_st my_charset_utf8mb3_unicode_ci;
extern struct charset_info_st my_charset_utf8mb3_unicode_nopad_ci;
-extern struct charset_info_st my_charset_utf8mb4_bin;
+extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_utf8mb4_bin;
extern struct charset_info_st my_charset_utf8mb4_general_ci;
extern struct charset_info_st my_charset_utf8mb4_nopad_bin;
extern struct charset_info_st my_charset_utf8mb4_general_nopad_ci;
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 8137bca570b..68d4fb0f0c8 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -426,12 +426,10 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp);
#define MYF_NO_DEADLOCK_DETECTION 2
#ifdef SAFE_MUTEX
-#define safe_mutex_assert_owner(mp) \
- DBUG_ASSERT((mp)->count > 0 && \
- pthread_equal(pthread_self(), (mp)->thread))
-#define safe_mutex_assert_not_owner(mp) \
- DBUG_ASSERT(! (mp)->count || \
- ! pthread_equal(pthread_self(), (mp)->thread))
+#define safe_mutex_is_owner(mp) ((mp)->count > 0 && \
+ pthread_equal(pthread_self(), (mp)->thread))
+#define safe_mutex_assert_owner(mp) DBUG_ASSERT(safe_mutex_is_owner(mp))
+#define safe_mutex_assert_not_owner(mp) DBUG_ASSERT(!safe_mutex_is_owner(mp))
#define safe_mutex_setflags(mp, F) do { (mp)->create_flags|= (F); } while (0)
#define my_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
#define my_cond_wait(A,B) safe_cond_wait((A), (B), __FILE__, __LINE__)
diff --git a/include/my_sys.h b/include/my_sys.h
index dceae9b889e..2ad4e131b3f 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -463,18 +463,19 @@ typedef struct st_io_cache /* Used when caching files */
partial.
*/
int seek_not_done,error;
- /* buffer_length is memory size allocated for buffer or write_buffer */
+ /* length of the buffer used for storing un-encrypted data */
size_t buffer_length;
/* read_length is the same as buffer_length except when we use async io */
size_t read_length;
myf myflags; /* Flags used to my_read/my_write */
/*
- alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
- 0 if it was supplied by the user.
+ alloced_buffer is set to the size of the buffer allocated for the IO_CACHE.
+ Includes the overhead(storing key to ecnrypt and decrypt) for encryption.
+ Set to 0 if nothing is allocated.
Currently READ_NET is the only one that will use a buffer allocated
somewhere else
*/
- my_bool alloced_buffer;
+ size_t alloced_buffer;
} IO_CACHE;
typedef int (*qsort2_cmp)(const void *, const void *, const void *);
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
index 711520dba78..47f89f76685 100644
--- a/include/mysql/psi/mysql_thread.h
+++ b/include/mysql/psi/mysql_thread.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2013, Oracle and/or its affiliates.
+ 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, version 2.0,
@@ -262,6 +263,7 @@ typedef struct st_mysql_cond mysql_cond_t;
*/
#ifndef DISABLE_MYSQL_THREAD_H
+#define mysql_mutex_is_owner(M) safe_mutex_is_owner(&(M)->m_mutex)
/**
@def mysql_mutex_assert_owner(M)
Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
diff --git a/include/mysql_version.h.in b/include/mysql_version.h.in
index ad719634335..82a13283e3f 100644
--- a/include/mysql_version.h.in
+++ b/include/mysql_version.h.in
@@ -18,13 +18,16 @@
#define MYSQL_SERVER_SUFFIX_DEF "@MYSQL_SERVER_SUFFIX@"
#define FRM_VER @DOT_FRM_VERSION@
#define MYSQL_VERSION_ID @MYSQL_VERSION_ID@
-#define MYSQL_PORT @MYSQL_TCP_PORT@
+#define MARIADB_PORT @MYSQL_TCP_PORT@
#define MYSQL_PORT_DEFAULT @MYSQL_TCP_PORT_DEFAULT@
-#define MYSQL_UNIX_ADDR "@MYSQL_UNIX_ADDR@"
+#define MARIADB_UNIX_ADDR "@MYSQL_UNIX_ADDR@"
#define MYSQL_CONFIG_NAME "my"
#define MYSQL_COMPILATION_COMMENT "@COMPILATION_COMMENT@"
#define SERVER_MATURITY_LEVEL @SERVER_MATURITY_LEVEL@
+#define MYSQL_PORT MARIADB_PORT
+#define MYSQL_UNIX_ADDR MARIADB_UNIX_ADDR
+
#ifdef WITH_WSREP
#define WSREP_PATCH_VERSION "@WSREP_PATCH_VERSION@"
#endif
diff --git a/libmariadb b/libmariadb
-Subproject a746c3af449a8754e78ad7971e59e79af7957cd
+Subproject 62427520a5ba20e42fe51f5045062a7a9cadb46
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 213238b6dbf..d2f7d40c1b4 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -159,7 +159,7 @@ ENDIF()
SET(LIBS
dbug strings mysys mysys_ssl pcre2-8 vio
${ZLIB_LIBRARY} ${SSL_LIBRARIES}
- ${LIBWRAP} ${LIBCRYPT} ${LIBDL}
+ ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS}
${EMBEDDED_PLUGIN_LIBS}
sql_embedded
)
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 21227e78a39..b1a467db3c6 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -332,7 +332,7 @@ static my_bool emb_read_query_result(MYSQL *mysql)
static int emb_stmt_execute(MYSQL_STMT *stmt)
{
DBUG_ENTER("emb_stmt_execute");
- uchar header[5];
+ uchar header[9];
THD *thd;
my_bool res;
@@ -344,6 +344,7 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
int4store(header, stmt->stmt_id);
header[4]= (uchar) stmt->flags;
+ header[5]= header[6]= header[7]= header[8]= 0; // safety
thd= (THD*)stmt->mysql->thd;
thd->client_param_count= stmt->param_count;
thd->client_params= stmt->params;
diff --git a/man/mysqlimport.1 b/man/mysqlimport.1
index ecf616d1cb8..56530f22628 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/include/have_static_innodb.inc b/mysql-test/include/have_static_innodb.inc
new file mode 100644
index 00000000000..0d7bb856f4f
--- /dev/null
+++ b/mysql-test/include/have_static_innodb.inc
@@ -0,0 +1,7 @@
+source include/have_innodb.inc;
+
+if (!`select count(*) from information_schema.plugins
+ where plugin_name = 'innodb' and plugin_status = 'active' and
+ plugin_library is null`) {
+ skip Need compiled-in InnoDB;
+}
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/mtr_check.sql b/mysql-test/include/mtr_check.sql
index a537f008183..76cd06e5d38 100644
--- a/mysql-test/include/mtr_check.sql
+++ b/mysql-test/include/mtr_check.sql
@@ -35,6 +35,7 @@ BEGIN
AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP'
AND variable_name not like 'GTID%POS'
AND variable_name != 'GTID_BINLOG_STATE'
+ AND variable_name != 'THREAD_POOL_SIZE'
ORDER BY variable_name;
-- Dump all databases, there should be none
diff --git a/mysql-test/include/not_true.require b/mysql-test/include/not_true.require
deleted file mode 100644
index 0032832f3d1..00000000000
--- a/mysql-test/include/not_true.require
+++ /dev/null
@@ -1,2 +0,0 @@
-TRUE
-NULL
diff --git a/mysql-test/include/rowid_filter_debug_kill.inc b/mysql-test/include/rowid_filter_debug_kill.inc
new file mode 100644
index 00000000000..6a8c5d3f70d
--- /dev/null
+++ b/mysql-test/include/rowid_filter_debug_kill.inc
@@ -0,0 +1,68 @@
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/count_sessions.inc
+
+--echo #
+--echo # MDEV-22761 KILL QUERY during rowid_filter, crashes
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+
+# 100 rows
+create table t2(a int);
+insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+
+# 10K rows
+CREATE TABLE t3 (
+ key1 int ,
+ key2 int,
+ filler varchar(255),
+ KEY (key1),
+ KEY (key2)
+);
+select engine from information_schema.tables
+where table_schema=database() and table_name='t3';
+
+insert into t3
+select
+ A.a,
+ A.a,
+ 'filler-data-filler-data'
+from
+ t0 A, t1 B;
+
+analyze table t2,t3;
+
+explain
+select * from t2, t3
+where
+ t3.key1=t2.a and t3.key2 in (2,3);
+
+let $target_id= `select connection_id()`;
+
+set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go';
+send
+select * from t2, t3
+where
+ t3.key1=t2.a and t3.key2 in (2,3);
+
+connect (con1, localhost, root,,);
+connection con1;
+set debug_sync='now WAIT_FOR at_rowid_filter_check';
+evalp kill query $target_id;
+set debug_sync='now SIGNAL go';
+
+connection default;
+disconnect con1;
+
+--error ER_QUERY_INTERRUPTED
+reap;
+set debug_sync='RESET';
+
+drop table t0,t1,t2,t3;
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
index 44c0e6eb8cb..eac1f1be8bd 100644
--- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt
+++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
@@ -26,7 +26,7 @@ ENDIF()
IF(WITH_WSREP)
ADD_EXECUTABLE(wsrep_check_version wsrep_check_version.c)
- TARGET_LINK_LIBRARIES(wsrep_check_version ${LIBDL})
+ TARGET_LINK_LIBRARIES(wsrep_check_version ${CMAKE_DL_LIBS})
ENDIF()
IF(NOT INSTALL_MYSQLTESTDIR)
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 97fbdcae838..b61333535dc 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -745,7 +745,7 @@ sub collect_one_test_case {
if ( $enable_disabled )
{
# User has selected to run all disabled tests
- mtr_report(" - $tinfo->{name} wil be run although it's been disabled\n",
+ mtr_report(" - $tinfo->{name} will be run although it's been disabled\n",
" due to '$disable'");
}
else
diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result
index 197e52b35ca..a27b54d4b48 100644
--- a/mysql-test/main/alter_table.result
+++ b/mysql-test/main/alter_table.result
@@ -2521,6 +2521,17 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2, t1;
#
+# MDEV-18163: Assertion `table_share->tmp_table != NO_TMP_TABLE ||
+# m_lock_type != 2' failed in handler::ha_rnd_next(); / Assertion
+# `table_list->table' failed in find_field_in_table_ref / ERROR 1901
+# (on optimized builds)
+#
+CREATE TABLE t1 (k1 varchar(10) DEFAULT 5);
+CREATE TABLE t2 (i1 int);
+ALTER TABLE t1 ALTER COLUMN k1 SET DEFAULT (SELECT 1 FROM t2 limit 1);
+ERROR HY000: Function or expression 'select ...' cannot be used in the DEFAULT clause of `k1`
+DROP TABLE t1,t2;
+#
# End of 10.2 tests
#
#
@@ -3322,5 +3333,28 @@ Note 1176 Key 'x' doesn't exist in table 't1'
unlock tables;
drop table t1;
#
+# MDEV-23852 alter table rename column to uppercase doesn't work
+#
+create table t1 (abc int);
+alter table t1 rename column abc to Abc, algorithm=copy;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `Abc` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 rename column abc to ABc, algorithm=inplace;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `ABc` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 rename column abc to ABC;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `ABC` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+#
# End of 10.5 tests
#
diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test
index 6fe61a3222a..5fd1358e9a9 100644
--- a/mysql-test/main/alter_table.test
+++ b/mysql-test/main/alter_table.test
@@ -2037,6 +2037,20 @@ SHOW CREATE TABLE t2;
DROP TABLE t2, t1;
--echo #
+--echo # MDEV-18163: Assertion `table_share->tmp_table != NO_TMP_TABLE ||
+--echo # m_lock_type != 2' failed in handler::ha_rnd_next(); / Assertion
+--echo # `table_list->table' failed in find_field_in_table_ref / ERROR 1901
+--echo # (on optimized builds)
+--echo #
+
+
+CREATE TABLE t1 (k1 varchar(10) DEFAULT 5);
+CREATE TABLE t2 (i1 int);
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ALTER COLUMN k1 SET DEFAULT (SELECT 1 FROM t2 limit 1);
+DROP TABLE t1,t2;
+
+--echo #
--echo # End of 10.2 tests
--echo #
@@ -2530,5 +2544,17 @@ unlock tables;
drop table t1;
--echo #
+--echo # MDEV-23852 alter table rename column to uppercase doesn't work
+--echo #
+create table t1 (abc int);
+alter table t1 rename column abc to Abc, algorithm=copy;
+show create table t1;
+alter table t1 rename column abc to ABc, algorithm=inplace;
+show create table t1;
+alter table t1 rename column abc to ABC;
+show create table t1;
+drop table t1;
+
+--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/aria_icp_debug.result b/mysql-test/main/aria_icp_debug.result
new file mode 100644
index 00000000000..fc01ee4fb3b
--- /dev/null
+++ b/mysql-test/main/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/main/aria_icp_debug.test b/mysql-test/main/aria_icp_debug.test
new file mode 100644
index 00000000000..bbdd59d6012
--- /dev/null
+++ b/mysql-test/main/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/main/backup_locks.result b/mysql-test/main/backup_locks.result
index a3a66937cf9..1505c39f166 100644
--- a/mysql-test/main/backup_locks.result
+++ b/mysql-test/main/backup_locks.result
@@ -39,8 +39,129 @@ MDL_INTENTION_EXCLUSIVE Schema metadata lock test
select * from t1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
backup unlock;
+#
+# BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
+#
+CREATE PROCEDURE p_BACKUP_LOCK()
+BEGIN
+BACKUP LOCK;
+END|
+ERROR 0A000: BACKUP LOCK is not allowed in stored procedures
+CREATE PROCEDURE p_BACKUP_UNLOCK()
+BEGIN
+BACKUP UNLOCK;
+END|
+ERROR 0A000: BACKUP UNLOCK is not allowed in stored procedures
+#
+# BACKUP STAGE doesn't work when a BACKUP LOCK is active.
+#
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+BACKUP STAGE START;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+BACKUP UNLOCK;
+DROP TABLE t1;
+#
+# FLUSH TABLES WITH READ LOCK is not allowed when BACKUP LOCK is active.
+#
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+FLUSH TABLES t1 WITH READ LOCK;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+BACKUP UNLOCK;
+BACKUP LOCK t1;
+FLUSH TABLES WITH READ LOCK;
+BACKUP UNLOCK;
+UNLOCK TABLES;
+DROP TABLE t1;
+#
+# MDEV-20945 BACKUP UNLOCK assertion failures.
+#
+# Scenario 1.
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+FLUSH TABLE t1 WITH READ LOCK;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+BACKUP UNLOCK;
+DROP TABLE t1;
+# Scenario 2.
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+LOCK TABLES t2 AS a2 WRITE;
+BACKUP LOCK t1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+INSERT INTO t1 VALUES(0);
+# restart
+DROP TABLE t1;
+DROP TABLE t2;
+# Scenario 3.
+CREATE TEMPORARY TABLE t3 (c INT);
+BACKUP LOCK t1;
+SET @@SESSION.profiling=ON;
+CREATE TABLE t1 (c INT);
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+LOCK TABLES t3 AS a1 READ, t1 AS a3 READ, t3 AS a5 READ LOCAL;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLE;
+# restart
+# Scenario 4.
+CREATE TABLE t (c INT);
+BACKUP LOCK not_existing.t;
+LOCK TABLES t WRITE;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+# restart
+DROP TABLE t;
+# Scenario 5.
+BACKUP LOCK t1;
+CREATE TABLE t2 (c1 TIME, c2 TIME, c3 DATE, KEY(c1, c2));
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+LOCK TABLE t2 READ;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# restart
+# Scenario 6.
+BACKUP LOCK t;
+CREATE VIEW v AS SELECT 1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+LOCK TABLES v READ;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+START TRANSACTION READ ONLY;
+BACKUP LOCK t;
+# restart
+# Scenario 7.
+SET SQL_MODE='';
+SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
+CREATE TABLE t (a INT) ENGINE=Aria;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+CREATE TEMPORARY TABLE IF NOT EXISTS s (c INT) ENGINE=Aria;
+LOCK TABLES s AS a READ LOCAL,t AS b WRITE;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
+# restart
+#
connection con1;
connection default;
disconnect con1;
show tables;
Tables_in_test
+#
+# MDEV-22879 SIGSEGV (or hang) in free/my_free from
+# _ma_end_block_record (on optimized builds)
+#
+SET STATEMENT max_statement_time=20 FOR BACKUP LOCK test.t1;
+CREATE TABLE IF NOT EXISTS t3 (c1 CHAR(1) BINARY,c2 SMALLINT(10),c3 NUMERIC(1,0), PRIMARY KEY(c1(1))) ENGINE=InnoDB;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+BACKUP UNLOCK;
+CREATE TABLE IF NOT EXISTS t3 (c1 CHAR(1) BINARY,c2 SMALLINT(10),c3 NUMERIC(1,0), PRIMARY KEY(c1(1))) ENGINE=InnoDB;
+SET STATEMENT max_statement_time=20 FOR BACKUP LOCK test.t1;
+LOCK TABLES t3 AS a2 WRITE, t3 AS a1 READ LOCAL;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+DROP TABLE t3;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+BACKUP UNLOCK;
+DROP TABLE t3;
+#
+# End of MariaDB 10.4 tests
+#
diff --git a/mysql-test/main/backup_locks.test b/mysql-test/main/backup_locks.test
index 21b67100506..d2f3d95d703 100644
--- a/mysql-test/main/backup_locks.test
+++ b/mysql-test/main/backup_locks.test
@@ -43,8 +43,150 @@ SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.me
--error ER_LOCK_DEADLOCK
select * from t1;
backup unlock;
+
+--echo #
+--echo # BACKUP LOCK and BACKUP UNLOCK are not allowed in procedures.
+--echo #
+delimiter |;
+--error ER_SP_BADSTATEMENT
+CREATE PROCEDURE p_BACKUP_LOCK()
+BEGIN
+ BACKUP LOCK;
+END|
+--error ER_SP_BADSTATEMENT
+CREATE PROCEDURE p_BACKUP_UNLOCK()
+BEGIN
+ BACKUP UNLOCK;
+END|
+delimiter ;|
+
+--echo #
+--echo # BACKUP STAGE doesn't work when a BACKUP LOCK is active.
+--echo #
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+--error ER_CANT_UPDATE_WITH_READLOCK
+BACKUP STAGE START;
+BACKUP UNLOCK;
+DROP TABLE t1;
+
+--echo #
+--echo # FLUSH TABLES WITH READ LOCK is not allowed when BACKUP LOCK is active.
+--echo #
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+FLUSH TABLES t1 WITH READ LOCK;
+BACKUP UNLOCK;
+
+BACKUP LOCK t1;
+FLUSH TABLES WITH READ LOCK;
+BACKUP UNLOCK;
+UNLOCK TABLES;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-20945 BACKUP UNLOCK assertion failures.
+--echo #
+
+--echo # Scenario 1.
+CREATE TABLE t1 (a INT);
+BACKUP LOCK t1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+FLUSH TABLE t1 WITH READ LOCK;
+UNLOCK TABLES;
+BACKUP UNLOCK; # Shouldn't trigger an assertion.
+DROP TABLE t1;
+
+--echo # Scenario 2.
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT);
+LOCK TABLES t2 AS a2 WRITE;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+BACKUP LOCK t1;
+UNLOCK TABLES;
+INSERT INTO t1 VALUES(0);
+--source include/restart_mysqld.inc
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo # Scenario 3.
+CREATE TEMPORARY TABLE t3 (c INT);
+BACKUP LOCK t1; # Table `t1` doesn't exist.
+SET @@SESSION.profiling=ON;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE TABLE t1 (c INT);
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLES t3 AS a1 READ, t1 AS a3 READ, t3 AS a5 READ LOCAL;
+UNLOCK TABLE;
+--source include/restart_mysqld.inc
+
+--echo # Scenario 4.
+CREATE TABLE t (c INT);
+BACKUP LOCK not_existing.t;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLES t WRITE;
+UNLOCK TABLES;
+--source include/restart_mysqld.inc
+DROP TABLE t;
+
+--echo # Scenario 5.
+BACKUP LOCK t1;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE TABLE t2 (c1 TIME, c2 TIME, c3 DATE, KEY(c1, c2));
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLE t2 READ;
+--source include/restart_mysqld.inc
+
+--echo # Scenario 6.
+BACKUP LOCK t;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE VIEW v AS SELECT 1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLES v READ;
+START TRANSACTION READ ONLY;
+BACKUP LOCK t;
+--source include/restart_mysqld.inc
+
+--echo # Scenario 7.
+SET SQL_MODE='';
+SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE TABLE t (a INT) ENGINE=Aria;
+CREATE TEMPORARY TABLE IF NOT EXISTS s (c INT) ENGINE=Aria;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLES s AS a READ LOCAL,t AS b WRITE;
+--let $q= `SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE`
+SET STATEMENT max_statement_time=180 FOR BACKUP LOCK test.u;
+--source include/restart_mysqld.inc
+
+--echo #
+
connection con1;
--reap
connection default;
disconnect con1;
show tables;
+
+--echo #
+--echo # MDEV-22879 SIGSEGV (or hang) in free/my_free from
+--echo # _ma_end_block_record (on optimized builds)
+--echo #
+
+SET STATEMENT max_statement_time=20 FOR BACKUP LOCK test.t1;
+--error ER_CANT_UPDATE_WITH_READLOCK
+CREATE TABLE IF NOT EXISTS t3 (c1 CHAR(1) BINARY,c2 SMALLINT(10),c3 NUMERIC(1,0), PRIMARY KEY(c1(1))) ENGINE=InnoDB;
+BACKUP UNLOCK;
+
+CREATE TABLE IF NOT EXISTS t3 (c1 CHAR(1) BINARY,c2 SMALLINT(10),c3 NUMERIC(1,0), PRIMARY KEY(c1(1))) ENGINE=InnoDB;
+SET STATEMENT max_statement_time=20 FOR BACKUP LOCK test.t1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLES t3 AS a2 WRITE, t3 AS a1 READ LOCAL;
+--error ER_CANT_UPDATE_WITH_READLOCK
+DROP TABLE t3;
+BACKUP UNLOCK;
+DROP TABLE t3;
+
+--echo #
+--echo # End of MariaDB 10.4 tests
+--echo #
diff --git a/mysql-test/main/blackhole.result b/mysql-test/main/blackhole.result
index 36f5459ff85..a7281c42ca7 100644
--- a/mysql-test/main/blackhole.result
+++ b/mysql-test/main/blackhole.result
@@ -24,3 +24,9 @@ SELECT 0 FROM t1 FORCE INDEX FOR GROUP BY(a) WHERE a = 0 OR b = 0 AND c = 0;
0
DROP TABLE t1;
End of 5.6 tests
+CREATE TABLE `t` (
+`a` varchar(3000) NOT NULL default '',
+PRIMARY KEY (`a`)
+) ENGINE=BLACKHOLE;
+DROP TABLE `t`;
+End of 10.1 tests
diff --git a/mysql-test/main/blackhole.test b/mysql-test/main/blackhole.test
index 7f394e0f846..c80ceffef4c 100644
--- a/mysql-test/main/blackhole.test
+++ b/mysql-test/main/blackhole.test
@@ -38,3 +38,19 @@ SELECT 0 FROM t1 FORCE INDEX FOR GROUP BY(a) WHERE a = 0 OR b = 0 AND c = 0;
DROP TABLE t1;
--echo End of 5.6 tests
+
+#
+# MDEV-24017 / bug 53588 test case.
+#
+# Create long enough index (between 1000 and 3500). 1000 is the old value,
+# 3500 is innodb value (see ha_innobase::max_supported_key_length()). Without
+# the fix the test will fail with "Specified key was too long" error.
+#
+CREATE TABLE `t` (
+ `a` varchar(3000) NOT NULL default '',
+ PRIMARY KEY (`a`)
+) ENGINE=BLACKHOLE;
+
+DROP TABLE `t`;
+
+--echo End of 10.1 tests
diff --git a/mysql-test/main/bootstrap_innodb.result b/mysql-test/main/bootstrap_innodb.result
new file mode 100644
index 00000000000..2807a9776a5
--- /dev/null
+++ b/mysql-test/main/bootstrap_innodb.result
@@ -0,0 +1,8 @@
+create table t1(a int) engine=innodb;
+# restart
+select * from t1;
+a
+1
+2
+5
+drop table t1;
diff --git a/mysql-test/main/bootstrap_innodb.test b/mysql-test/main/bootstrap_innodb.test
new file mode 100644
index 00000000000..ddaefb32155
--- /dev/null
+++ b/mysql-test/main/bootstrap_innodb.test
@@ -0,0 +1,27 @@
+source include/have_static_innodb.inc;
+source include/not_embedded.inc;
+
+let $datadir= `select @@datadir`;
+
+create table t1(a int) engine=innodb;
+source include/shutdown_mysqld.inc;
+
+write_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql;
+use test;
+insert t1 values (1);
+start transaction;
+insert t1 values (2);
+savepoint s1;
+insert t1 values (3);
+savepoint s2;
+insert t1 values (4);
+rollback to savepoint s1;
+insert t1 values (5);
+commit;
+EOF
+exec $MYSQLD_BOOTSTRAP_CMD --datadir=$datadir --innodb < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1;
+remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql;
+
+source include/start_mysqld.inc;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/main/case.result b/mysql-test/main/case.result
index 926ac000eb0..f4f02703c5e 100644
--- a/mysql-test/main/case.result
+++ b/mysql-test/main/case.result
@@ -517,12 +517,12 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a' AND CASE 'a' WHEN 'a' THEN a ELSE
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and (case 'a' when 'a' then `test`.`t1`.`a` else 'a' end) = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and case 'a' when 'a' then `test`.`t1`.`a` else 'a' end = 'a'
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a' AND CASE 'a' WHEN 'a' THEN 'a' ELSE a END='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and (case 'a' when 'a' then 'a' else `test`.`t1`.`a` end) = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and case 'a' when 'a' then 'a' else `test`.`t1`.`a` end = 'a'
ALTER TABLE t1 MODIFY a VARBINARY(10);
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a' AND CASE a WHEN 'a' THEN 'a' ELSE 'a' END='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -570,7 +570,7 @@ CASE WHEN a THEN b ELSE 1 END=3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (case `test`.`t1`.`a` when `test`.`t1`.`b` then 1 end) = 1 and (case when `test`.`t1`.`a` then `test`.`t1`.`b` else 1 end) = 3
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where case `test`.`t1`.`a` when `test`.`t1`.`b` then 1 end = 1 and case when `test`.`t1`.`a` then `test`.`t1`.`b` else 1 end = 3
DROP TABLE t1;
#
# End of 10.3 test
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 85744451dc0..33e8eab968b 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -10024,11 +10024,11 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
- "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a = 2) then 1 else 0 end = 1",
+ "attached_condition": "case when tab2.max_a = 1 or tab2.max_a = 2 then 1 else 0 end = 1",
"materialized": {
"query_block": {
"select_id": 3,
- "having_condition": "case when (max_a = 1 or max_a = 2) then 1 else 0 end = 1",
+ "having_condition": "case when max_a = 1 or max_a = 2 then 1 else 0 end = 1",
"filesort": {
"sort_key": "t1.b",
"temporary_table": {
@@ -10073,11 +10073,11 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
- "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a > 2 and tab2.max_a < 4) then 1 else 0 end = 1",
+ "attached_condition": "case when tab2.max_a = 1 or tab2.max_a > 2 and tab2.max_a < 4 then 1 else 0 end = 1",
"materialized": {
"query_block": {
"select_id": 3,
- "having_condition": "case when (max_a = 1 or max_a > 2 and max_a < 4) then 1 else 0 end = 1",
+ "having_condition": "case when max_a = 1 or max_a > 2 and max_a < 4 then 1 else 0 end = 1",
"filesort": {
"sort_key": "t1.b",
"temporary_table": {
@@ -10122,11 +10122,11 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
- "attached_condition": "case when (tab2.max_a > 1 and (tab2.max_a = 2 or tab2.max_a > 2)) then 1 else 0 end = 1",
+ "attached_condition": "case when tab2.max_a > 1 and (tab2.max_a = 2 or tab2.max_a > 2) then 1 else 0 end = 1",
"materialized": {
"query_block": {
"select_id": 3,
- "having_condition": "case when (max_a > 1 and (max_a = 2 or max_a > 2)) then 1 else 0 end = 1",
+ "having_condition": "case when max_a > 1 and (max_a = 2 or max_a > 2) then 1 else 0 end = 1",
"filesort": {
"sort_key": "t1.b",
"temporary_table": {
@@ -10171,7 +10171,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
- "attached_condition": "case when (tab2.b = 2 or tab2.b = 4) then 1 else 0 end = 1",
+ "attached_condition": "case when tab2.b = 2 or tab2.b = 4 then 1 else 0 end = 1",
"materialized": {
"query_block": {
"select_id": 3,
@@ -10183,7 +10183,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
- "attached_condition": "case when (t1.b = 2 or t1.b = 4) then 1 else 0 end = 1"
+ "attached_condition": "case when t1.b = 2 or t1.b = 4 then 1 else 0 end = 1"
}
}
}
diff --git a/mysql-test/main/errors.result b/mysql-test/main/errors.result
index 78695b07b8e..44193865493 100644
--- a/mysql-test/main/errors.result
+++ b/mysql-test/main/errors.result
@@ -196,3 +196,38 @@ ERROR 22003: BIGINT value is out of range in '-73 * -2465717823867977728'
SELECT UPDATEXML(-73 * -2465717823867977728,@@global.long_query_time,null);
ERROR 22003: BIGINT value is out of range in '-73 * -2465717823867977728'
# End of 10.3 tests
+#
+# MDEV-23518: Syntax error in ond SP results in misleading
+# message on SHOW CREATE PROCEDURE
+#
+CREATE PROCEDURE P1 ()
+BEGIN NOT ATOMIC
+IF (SELECT 2) THEN
+SELECT 4;
+END IF ;
+END;
+$$
+select name,db,body from mysql.proc where name = "P1";
+name db body
+P1 test BEGIN NOT ATOMIC
+IF (SELECT 2) THEN
+SELECT 4;
+END IF ;
+END
+update mysql.proc set body_utf8="BEGIN NOT ATOMIC
+IF (SELECT 2) OR foo = 3 THEN
+SELECT 4;
+END IF ;
+END", body="BEGIN NOT ATOMIC
+IF (SELECT 2) OR foo = 3 THEN
+SELECT 4;
+END IF ;
+END"where name = "P1";
+show create procedure P1;
+ERROR HY000: Failed to load routine test.P1 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1327 Undeclared variable: foo
+Error 1457 Failed to load routine test.P1 (internal code -6). For more details, run SHOW WARNINGS
+drop procedure P1;
+# End of 10.4 tests
diff --git a/mysql-test/main/errors.test b/mysql-test/main/errors.test
index f3aedc8e491..a4b95d48e5d 100644
--- a/mysql-test/main/errors.test
+++ b/mysql-test/main/errors.test
@@ -246,3 +246,39 @@ SELECT UPDATEXML(-73 * -2465717823867977728,@@global.auto_increment_increment,nu
SELECT UPDATEXML(-73 * -2465717823867977728,@@global.long_query_time,null);
-- echo # End of 10.3 tests
+
+--echo #
+--echo # MDEV-23518: Syntax error in ond SP results in misleading
+--echo # message on SHOW CREATE PROCEDURE
+--echo #
+
+DELIMITER $$;
+
+CREATE PROCEDURE P1 ()
+BEGIN NOT ATOMIC
+ IF (SELECT 2) THEN
+ SELECT 4;
+ END IF ;
+END;
+$$
+
+DELIMITER ;$$
+
+select name,db,body from mysql.proc where name = "P1";
+update mysql.proc set body_utf8="BEGIN NOT ATOMIC
+IF (SELECT 2) OR foo = 3 THEN
+SELECT 4;
+END IF ;
+END", body="BEGIN NOT ATOMIC
+IF (SELECT 2) OR foo = 3 THEN
+SELECT 4;
+END IF ;
+END"where name = "P1";
+
+--error ER_SP_PROC_TABLE_CORRUPT
+show create procedure P1;
+show warnings;
+
+drop procedure P1;
+
+-- echo # End of 10.4 tests
diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result
index 9233393fd94..1fc92ba90cc 100644
--- a/mysql-test/main/func_group.result
+++ b/mysql-test/main/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.21328517
+0.21325764
select std(o1/o2) from bug22555;
std(o1/o2)
0.2132576358664934
select std(e1/e2) from bug22555;
std(e1/e2)
-0.21328517
+0.21325764
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/main/func_json.result b/mysql-test/main/func_json.result
index 523048ccb7a..14ab6f41bce 100644
--- a/mysql-test/main/func_json.result
+++ b/mysql-test/main/func_json.result
@@ -898,6 +898,11 @@ NULL
SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]');
JSON_MERGE_PATCH(NULL, '[1,2,3]')
[1, 2, 3]
+SELECT JSON_MERGE_PATCH(NULL, 'a');
+JSON_MERGE_PATCH(NULL, 'a')
+NULL
+Warnings:
+Warning 4038 Syntax error in JSON text in argument 2 to function 'json_merge_patch' at position 1
SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}');
JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}')
{"d": "e"}
@@ -1354,6 +1359,11 @@ e JSON_OBJECTAGG(B.a, B.v)
0 {"a1":"1", "a1":"1", "a1":"1"}
0 {"a2":"2", "a2":"2", "a2":"2"}
1 {"b1":"3", "b1":"3", "b1":"3"}
+CREATE VIEW v AS SELECT JSON_OBJECTAGG(a, e) FROM t1;
+SELECT * FROM v;
+JSON_OBJECTAGG(a, e)
+{"a1":0, "a2":0, "b1":1}
+DROP VIEW v;
DROP TABLE t1;
#
# End of 10.5 tests
diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test
index 68d381f5c07..a77f7d8bd5b 100644
--- a/mysql-test/main/func_json.test
+++ b/mysql-test/main/func_json.test
@@ -528,6 +528,7 @@ DROP TABLE merge_t;
SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '{"c":"d"}');
SELECT JSON_MERGE_PATCH(NULL, '[1,2,3]');
+SELECT JSON_MERGE_PATCH(NULL, 'a');
SELECT JSON_MERGE_PATCH('{"a":"b"}', NULL, '[1,2,3]', '{"c":null,"d":"e"}');
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
@@ -849,6 +850,10 @@ INSERT INTO t1 VALUES (0, 'a1', '1') , (0, 'a2', '2') , (1, 'b1', '3');
EXPLAIN SELECT B.e, JSON_OBJECTAGG(B.a, B.v) FROM t1 A, t1 B GROUP BY B.e, B.a;
SELECT B.e, JSON_OBJECTAGG(B.a, B.v) FROM t1 A, t1 B GROUP BY B.e, B.a;
+CREATE VIEW v AS SELECT JSON_OBJECTAGG(a, e) FROM t1;
+SELECT * FROM v;
+
+DROP VIEW v;
DROP TABLE t1;
--echo #
diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result
index 37188dab623..ec2521bcfd7 100644
--- a/mysql-test/main/func_math.result
+++ b/mysql-test/main/func_math.result
@@ -1765,11 +1765,6 @@ select 0=0, 0=-0, 0.0= -0.0, 0.0 = -(0.0), 0.0E1=-0.0E1, 0.0E1=-(0.0E1);
select CRC32(NULL), CRC32(''), CRC32('MySQL'), CRC32('mysql'), CRC32('01234567'), CRC32('012345678'), CRC32(REPEAT('ABCDEfghij', 20)), CRC32(REPEAT('0123456789', 200));
CRC32(NULL) CRC32('') CRC32('MySQL') CRC32('mysql') CRC32('01234567') CRC32('012345678') CRC32(REPEAT('ABCDEfghij', 20)) CRC32(REPEAT('0123456789', 200))
NULL 0 3259397556 2501908538 763378421 939184570 3823776386 1428305034
-explain extended select (3-2)+1, (3/2)*1, 3-(2+1), 3/(2*1);
-id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
-Warnings:
-Note 1003 select 3 - 2 + 1 AS `(3-2)+1`,3 / 2 * 1 AS `(3/2)*1`,3 - (2 + 1) AS `3-(2+1)`,3 / (2 * 1) AS `3/(2*1)`
#
# Start of 10.3 tests
#
diff --git a/mysql-test/main/func_math.test b/mysql-test/main/func_math.test
index 6bce8bdaad6..572e0fd0f6b 100644
--- a/mysql-test/main/func_math.test
+++ b/mysql-test/main/func_math.test
@@ -793,11 +793,6 @@ select 0=0, 0=-0, 0.0= -0.0, 0.0 = -(0.0), 0.0E1=-0.0E1, 0.0E1=-(0.0E1);
select CRC32(NULL), CRC32(''), CRC32('MySQL'), CRC32('mysql'), CRC32('01234567'), CRC32('012345678'), CRC32(REPEAT('ABCDEfghij', 20)), CRC32(REPEAT('0123456789', 200));
-#
-# MDEV-13673 Bad result in view
-#
-explain extended select (3-2)+1, (3/2)*1, 3-(2+1), 3/(2*1);
-
--echo #
--echo # Start of 10.3 tests
--echo #
diff --git a/mysql-test/main/func_test.result b/mysql-test/main/func_test.result
index 4243ed9cfb0..04aee8b5522 100644
--- a/mysql-test/main/func_test.result
+++ b/mysql-test/main/func_test.result
@@ -89,15 +89,6 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select -1 AS `- a` from dual
drop table t1;
-select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
-5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
-0 1
-select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
-1 and 2 between 2 and 10 2 between 2 and 10 and 1
-1 1
-select 1 and 0 or 2, 2 or 1 and 0;
-1 and 0 or 2 2 or 1 and 0
-1 1
select _koi8r'a' = _koi8r'A';
_koi8r'a' = _koi8r'A'
1
@@ -273,16 +264,6 @@ NULL
select mod(NULL, 2.0) as 'NULL';
NULL
NULL
-create table t1 (a int, b int);
-insert into t1 values (1,2), (2,3), (3,4), (4,5);
-select * from t1 where a not between 1 and 2;
-a b
-3 4
-4 5
-select * from t1 where a not between 1 and 2 and b not between 3 and 4;
-a b
-4 5
-drop table t1;
SELECT GREATEST(1,NULL) FROM DUAL;
GREATEST(1,NULL)
NULL
diff --git a/mysql-test/main/func_test.test b/mysql-test/main/func_test.test
index d1c0702da80..570fd0ae87a 100644
--- a/mysql-test/main/func_test.test
+++ b/mysql-test/main/func_test.test
@@ -36,14 +36,6 @@ explain extended select - a from t1;
drop table t1;
#
-# Wrong usage of functions
-#
-
-select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
-select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
-select 1 and 0 or 2, 2 or 1 and 0;
-
-#
# Coercibility
#
select _koi8r'a' = _koi8r'A';
@@ -142,15 +134,6 @@ select mod(NULL, 2.0) as 'NULL';
#
-# Bug#6726: NOT BETWEEN parse failure
-#
-create table t1 (a int, b int);
-insert into t1 values (1,2), (2,3), (3,4), (4,5);
-select * from t1 where a not between 1 and 2;
-select * from t1 where a not between 1 and 2 and b not between 3 and 4;
-drop table t1;
-
-#
# Test for bug #12791: one of the arguments of LEAST/GREATEST is NULL
#
diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result
index 972131a24b7..9f6eb583e91 100644
--- a/mysql-test/main/grant5.result
+++ b/mysql-test/main/grant5.result
@@ -39,6 +39,42 @@ disconnect u1;
drop user u1@localhost;
drop database mysqltest1;
#
+# MDEV-22313: Neither SHOW CREATE USER nor SHOW GRANTS prints a user's default role
+#
+CREATE ROLE test_role;
+CREATE USER test_user;
+GRANT test_role TO test_user;
+SET DEFAULT ROLE test_role FOR test_user;
+SHOW GRANTS FOR test_user;
+Grants for test_user@%
+GRANT `test_role` TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_user`@`%`
+SET DEFAULT ROLE test_role FOR 'test_user'@'%'
+SET DEFAULT ROLE NONE for test_user;
+SHOW GRANTS FOR test_user;
+Grants for test_user@%
+GRANT `test_role` TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_user`@`%`
+connect test_user, localhost, test_user;
+SET ROLE test_role;
+SET DEFAULT ROLE test_role;
+SHOW GRANTS;
+Grants for test_user@%
+GRANT `test_role` TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_role`
+SET DEFAULT ROLE test_role FOR 'test_user'@'%'
+SET DEFAULT ROLE NONE;
+SHOW GRANTS;
+Grants for test_user@%
+GRANT `test_role` TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_user`@`%`
+GRANT USAGE ON *.* TO `test_role`
+disconnect test_user;
+connection default;
+DROP USER test_user;
+DROP ROLE test_role;
+#
# MDEV-20076: SHOW GRANTS does not quote role names properly
#
create role 'role1';
diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test
index e133108516e..9c3f20396c4 100644
--- a/mysql-test/main/grant5.test
+++ b/mysql-test/main/grant5.test
@@ -51,6 +51,27 @@ disconnect u1;
drop user u1@localhost;
drop database mysqltest1;
+--echo #
+--echo # MDEV-22313: Neither SHOW CREATE USER nor SHOW GRANTS prints a user's default role
+--echo #
+CREATE ROLE test_role;
+CREATE USER test_user;
+GRANT test_role TO test_user;
+SET DEFAULT ROLE test_role FOR test_user;
+SHOW GRANTS FOR test_user;
+SET DEFAULT ROLE NONE for test_user;
+SHOW GRANTS FOR test_user;
+connect test_user, localhost, test_user;
+SET ROLE test_role;
+SET DEFAULT ROLE test_role;
+SHOW GRANTS;
+SET DEFAULT ROLE NONE;
+SHOW GRANTS;
+disconnect test_user;
+connection default;
+DROP USER test_user;
+DROP ROLE test_role;
+
#
# End of 10.1 tests
#
diff --git a/mysql-test/main/implicit_commit.result b/mysql-test/main/implicit_commit.result
index b0cd0b75e8d..911aec085d8 100644
--- a/mysql-test/main/implicit_commit.result
+++ b/mysql-test/main/implicit_commit.result
@@ -1035,6 +1035,16 @@ YES
# SQLCOM_BACKUP
#
#
+# SQLCOM_BACKUP_LOCK
+#
+INSERT INTO db1.trans VALUES (1);
+BACKUP LOCK t1;
+ROLLBACK;
+BACKUP UNLOCK;
+CALL db1.test_if_commit();
+IMPLICIT COMMIT
+YES
+#
# SQLCOM_SHOW_ARCHIVE
#
#
diff --git a/mysql-test/main/implicit_commit.test b/mysql-test/main/implicit_commit.test
index bcc43865395..09f2e2e921e 100644
--- a/mysql-test/main/implicit_commit.test
+++ b/mysql-test/main/implicit_commit.test
@@ -1115,6 +1115,16 @@ source include/implicit_commit_helper.inc;
#source include/implicit_commit_helper.inc;
--echo #
+--echo # SQLCOM_BACKUP_LOCK
+--echo #
+
+INSERT INTO db1.trans VALUES (1);
+BACKUP LOCK t1;
+ROLLBACK;
+BACKUP UNLOCK;
+CALL db1.test_if_commit();
+
+--echo #
--echo # SQLCOM_SHOW_ARCHIVE
--echo #
diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result
index c070b41e54d..44407dbcd30 100644
--- a/mysql-test/main/index_intersect_innodb.result
+++ b/mysql-test/main/index_intersect_innodb.result
@@ -81,7 +81,7 @@ EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 300000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City index_merge Population,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+1 SIMPLE City range Population,Name Name 35 NULL # Using index condition; Using where
EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 7000000;
@@ -381,7 +381,7 @@ EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City index_merge Population,Name,Country Name,Population,Country # NULL # Using sort_intersect(Name,Population,Country); Using where
+1 SIMPLE City range Population,Name,Country Name # NULL # Using index condition; Using where
SELECT * FROM City USE INDEX ()
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
ID Name Country Population
@@ -721,7 +721,7 @@ EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City index_merge Population,Country,Name Name,Population,Country 35,4,3 NULL # Using sort_intersect(Name,Population,Country); Using where
+1 SIMPLE City range Population,Country,Name Name 35 NULL # Using index condition; Using where
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%';
@@ -732,7 +732,7 @@ SELECT * FROM City
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
AND Country BETWEEN 'S' AND 'Z';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where
+1 SIMPLE City range PRIMARY,Population,Country PRIMARY 4 NULL # Using where
SELECT * FROM City WHERE
Name LIKE 'C%' AND Population > 1000000;
ID Name Country Population
diff --git a/mysql-test/main/index_merge_myisam.result b/mysql-test/main/index_merge_myisam.result
index eee12a3811f..1a4906801a0 100644
--- a/mysql-test/main/index_merge_myisam.result
+++ b/mysql-test/main/index_merge_myisam.result
@@ -1689,7 +1689,7 @@ EXPLAIN
SELECT * FROM t1 FORCE KEY (PRIMARY , i , c1 , c2)
WHERE pk = 255 OR i = 22 OR (pk IN (1 , 136) AND c2 IN ('c' , 'w') AND (c1 NOT BETWEEN 'e' AND 'i' OR c2 > 'g')) OR pk != 1 ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY,c1,i,c2 NULL NULL NULL 69 Using where
+1 SIMPLE t1 index_merge PRIMARY,c1,i,c2 PRIMARY,i 0,5 NULL 69 Using sort_union(PRIMARY,i); Using where
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
#
diff --git a/mysql-test/main/innodb_ext_key,off.rdiff b/mysql-test/main/innodb_ext_key,off.rdiff
index 195456958d8..4d6c65c9971 100644
--- a/mysql-test/main/innodb_ext_key,off.rdiff
+++ b/mysql-test/main/innodb_ext_key,off.rdiff
@@ -1,9 +1,11 @@
+--- innodb_ext_key.result
++++ innodb_ext_key,off.result
@@ -9,7 +9,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
++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_orderkey=130 and l_shipdate='1992-07-01';
count(*)
@@ -12,7 +14,7 @@
Handler_read_key 1
Handler_read_last 0
-Handler_read_next 1
-+Handler_read_next 5
++Handler_read_next 6
Handler_read_prev 0
Handler_read_retry 0
Handler_read_rnd 0
@@ -93,7 +95,7 @@
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
++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 max(l_linenumber) from lineitem
where l_shipdate='1992-07-01' and l_orderkey=130;
@@ -102,7 +104,7 @@
Handler_read_key 1
Handler_read_last 0
-Handler_read_next 0
-+Handler_read_next 5
++Handler_read_next 6
Handler_read_prev 0
Handler_read_retry 0
Handler_read_rnd 0
@@ -132,8 +134,8 @@
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
+-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate # 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 # 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)
@@ -154,21 +156,18 @@
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
+-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 # NULL # Using
++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 # NULL # Using
flush status;
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
-@@ -223,7 +223,7 @@
- Handler_read_first 0
- Handler_read_key 2
- Handler_read_last 0
+@@ -220,12 +220,12 @@
+ 5959 3
+ show status like 'handler_read_next';
+ Variable_name Value
-Handler_read_next 3
+Handler_read_next 9
- Handler_read_prev 0
- Handler_read_retry 0
- Handler_read_rnd 3
-@@ -233,7 +233,7 @@
+ 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
@@ -177,7 +176,7 @@
flush status;
select max(l_orderkey) from lineitem
where l_partkey between 1 and 10 group by l_partkey;
-@@ -251,9 +251,9 @@
+@@ -243,9 +243,9 @@
show status like 'handler_read%';
Variable_name Value
Handler_read_first 0
@@ -190,7 +189,7 @@
Handler_read_prev 0
Handler_read_retry 0
Handler_read_rnd 0
-@@ -263,7 +263,7 @@
+@@ -255,7 +255,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
@@ -199,7 +198,7 @@
flush status;
select max(l_orderkey) from lineitem
where l_suppkey in (1,4) group by l_suppkey;
-@@ -273,9 +273,9 @@
+@@ -265,9 +265,9 @@
show status like 'handler_read%';
Variable_name Value
Handler_read_first 0
@@ -212,7 +211,7 @@
Handler_read_prev 0
Handler_read_retry 0
Handler_read_rnd 0
-@@ -291,7 +291,7 @@
+@@ -283,7 +283,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
@@ -221,7 +220,7 @@
flush status;
select o_orderkey, p_partkey
from part use index (i_p_retailprice),
-@@ -305,7 +305,7 @@
+@@ -297,7 +297,7 @@
Handler_read_first 0
Handler_read_key 3
Handler_read_last 0
@@ -230,7 +229,7 @@
Handler_read_prev 0
Handler_read_retry 0
Handler_read_rnd 0
-@@ -322,8 +322,8 @@
+@@ -314,8 +314,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
@@ -241,7 +240,7 @@
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
-@@ -502,7 +502,7 @@
+@@ -494,7 +494,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
@@ -250,7 +249,7 @@
drop table t1,t2,t3;
#
# Bug mdev-4340: performance regression with extended_keys=on
-@@ -722,13 +722,13 @@
+@@ -714,13 +714,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
@@ -266,7 +265,7 @@
drop table t0,t1,t2;
#
# MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff'
-@@ -763,11 +763,12 @@
+@@ -755,11 +755,12 @@
"select_id": 1,
"table": {
"table_name": "t1",
@@ -282,7 +281,7 @@
"rows": 1,
"filtered": 100,
"index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'",
-@@ -796,8 +797,8 @@
+@@ -788,8 +789,8 @@
"access_type": "range",
"possible_keys": ["k1"],
"key": "k1",
diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result
index e00192e1d64..5708cf88934 100644
--- a/mysql-test/main/innodb_ext_key.result
+++ b/mysql-test/main/innodb_ext_key.result
@@ -26,12 +26,12 @@ Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
explain
-select count(*) from lineitem
+select count(*) from lineitem use index(primary)
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
+1 SIMPLE lineitem const PRIMARY PRIMARY 8 const,const 1
flush status;
-select count(*) from lineitem
+select count(*) from lineitem use index(primary)
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
count(*)
1
@@ -183,7 +183,7 @@ 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 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 # NULL 3 Using sort_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)
@@ -209,7 +209,7 @@ 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,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,i_l_receiptdate # NULL # Using
flush status;
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
@@ -218,17 +218,9 @@ l_orderkey l_linenumber
130 2
5603 2
5959 3
-show status like 'handler_read%';
+show status like 'handler_read_next';
Variable_name Value
-Handler_read_first 0
-Handler_read_key 2
-Handler_read_last 0
Handler_read_next 3
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 3
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
explain
select max(l_orderkey) from lineitem
where l_partkey between 1 and 10 group by l_partkey;
diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test
index 2f6097c7850..5fcf6a309b9 100644
--- a/mysql-test/main/innodb_ext_key.test
+++ b/mysql-test/main/innodb_ext_key.test
@@ -17,6 +17,7 @@ use dbt3_s001;
--disable_result_log
--disable_warnings
--source include/dbt3_s001.inc
+ANALYZE TABLE lineitem PERSISTENT FOR COLUMNS() INDEXES();
--enable_warnings
--enable_result_log
--enable_query_log
@@ -28,10 +29,10 @@ select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
show status like 'handler_read%';
explain
-select count(*) from lineitem
+select count(*) from lineitem use index(primary)
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
flush status;
-select count(*) from lineitem
+select count(*) from lineitem use index(primary)
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
show status like 'handler_read%';
@@ -85,6 +86,7 @@ select l_orderkey, l_linenumber
or l_receiptdate='1992-07-01' and l_orderkey=5603;
show status like 'handler_read%';
+--replace_column 7 #
explain
select l_orderkey, l_linenumber
from lineitem use index (i_l_shipdate, i_l_receiptdate)
@@ -97,6 +99,7 @@ select l_orderkey, l_linenumber
or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
show status like 'handler_read%';
+--replace_column 7 # 9 # 10 Using
explain
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
@@ -105,7 +108,7 @@ 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%';
+show status like 'handler_read_next';
--replace_column 9 #
explain
diff --git a/mysql-test/main/innodb_icp_debug.result b/mysql-test/main/innodb_icp_debug.result
new file mode 100644
index 00000000000..5a169650c8e
--- /dev/null
+++ b/mysql-test/main/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/main/innodb_icp_debug.test b/mysql-test/main/innodb_icp_debug.test
new file mode 100644
index 00000000000..4aa08c61e87
--- /dev/null
+++ b/mysql-test/main/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/main/kill.result b/mysql-test/main/kill.result
index 55839817fd4..1ea06aee096 100644
--- a/mysql-test/main/kill.result
+++ b/mysql-test/main/kill.result
@@ -375,8 +375,7 @@ SELECT SLEEP(1000);
connection con1;
KILL QUERY ID @id;
connection default;
-SLEEP(1000)
-1
+ERROR 70100: Query execution was interrupted
KILL QUERY ID 0;
ERROR HY000: Unknown query id: 0
#
@@ -392,8 +391,7 @@ ERROR HY000: You are not owner of query ID
connection con1;
KILL QUERY ID @id;
connection default;
-SLEEP(1000)
-1
+ERROR 70100: Query execution was interrupted
disconnect con5;
DROP USER u1@localhost;
SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/main/kill.test b/mysql-test/main/kill.test
index 728b6b964e2..a3962e9dc49 100644
--- a/mysql-test/main/kill.test
+++ b/mysql-test/main/kill.test
@@ -606,6 +606,7 @@ let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WH
source include/wait_condition.inc;
KILL QUERY ID @id;
connection default;
+--error ER_QUERY_INTERRUPTED
reap;
--error ER_NO_SUCH_QUERY
@@ -632,6 +633,7 @@ connection con1;
KILL QUERY ID @id;
connection default;
+--error ER_QUERY_INTERRUPTED
reap;
disconnect con5;
DROP USER u1@localhost;
diff --git a/mysql-test/main/limit_rows_examined.result b/mysql-test/main/limit_rows_examined.result
index 2c208fd5d4c..f0a22b8f3f2 100644
--- a/mysql-test/main/limit_rows_examined.result
+++ b/mysql-test/main/limit_rows_examined.result
@@ -865,6 +865,21 @@ Warning 1931 Query execution was interrupted. The query examined at least 22 row
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 3 rows, which exceeds LIMIT ROWS EXAMINED (2). The query result may be incomplete
+SET @@sql_mode=@old_mode;
+DROP TABLE t1;
+#
# MDEV-18117: Crash with Explain extended when using limit rows examined
#
create table t1 (c1 char(2));
@@ -879,3 +894,4 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`c2` = `test`.`t1`.`c1`
drop table t1,t2;
+# End of 10.4 tests
diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test
index 2bac49f0dda..2315580410f 100644
--- a/mysql-test/main/limit_rows_examined.test
+++ b/mysql-test/main/limit_rows_examined.test
@@ -579,6 +579,23 @@ 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;
+
+--echo #
--echo # MDEV-18117: Crash with Explain extended when using limit rows examined
--echo #
@@ -589,3 +606,5 @@ insert into t2 values ('bb'), ('cc'), ('dd'), ('ff');
explain extended
select * from t1, t2 where c1 = c2 LIMIT ROWS EXAMINED 2;
drop table t1,t2;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/main/lock_view.result b/mysql-test/main/lock_view.result
new file mode 100644
index 00000000000..4d375bace42
--- /dev/null
+++ b/mysql-test/main/lock_view.result
@@ -0,0 +1,231 @@
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create user invoker@localhost;
+create user definer@localhost;
+grant select,show view on mysqltest1.* to invoker@localhost;
+grant select,show view on mysqltest1.* to definer@localhost;
+grant select,show view on mysqltest2.* to invoker@localhost;
+grant select,show view on mysqltest2.* to definer@localhost;
+grant select,show view on mysqltest3.* to invoker@localhost;
+grant select on performance_schema.* to definer@localhost;
+create table mysqltest1.t1 (a int);
+create definer=definer@localhost view mysqltest2.v2 as select * from mysqltest1.t1;
+create definer=definer@localhost view mysqltest3.v3 as select * from mysqltest2.v2;
+create definer=definer@localhost view mysqltest3.v3is as select schema_name from information_schema.schemata order by schema_name;
+create definer=definer@localhost view mysqltest3.v3ps as select user from performance_schema.users where current_connections>0 order by user;
+create definer=definer@localhost view mysqltest3.v3nt as select 1;
+create definer=definer@localhost sql security invoker view mysqltest3.v3i as select * from mysqltest1.t1;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `mysqltest1`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `mysqltest2`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v2` (
+ `a` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `mysqltest3`;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v3` (
+ `a` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v3i` (
+ `a` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v3is` (
+ `schema_name` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v3nt` (
+ `1` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+SET @saved_cs_client = @@character_set_client;
+SET character_set_client = utf8;
+/*!50001 CREATE TABLE `v3ps` (
+ `user` tinyint NOT NULL
+) ENGINE=MyISAM */;
+SET character_set_client = @saved_cs_client;
+
+USE `mysqltest1`;
+
+USE `mysqltest2`;
+/*!50001 DROP TABLE IF EXISTS `v2`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v2` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+
+USE `mysqltest3`;
+/*!50001 DROP TABLE IF EXISTS `v3`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v3` AS select `v2`.`a` AS `a` from `mysqltest2`.`v2` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+/*!50001 DROP TABLE IF EXISTS `v3i`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY INVOKER */
+/*!50001 VIEW `v3i` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+/*!50001 DROP TABLE IF EXISTS `v3is`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v3is` AS select `information_schema`.`schemata`.`SCHEMA_NAME` AS `schema_name` from `information_schema`.`schemata` order by `information_schema`.`schemata`.`SCHEMA_NAME` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+/*!50001 DROP TABLE IF EXISTS `v3nt`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v3nt` AS select 1 AS `1` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+/*!50001 DROP TABLE IF EXISTS `v3ps`*/;
+/*!50001 SET @saved_cs_client = @@character_set_client */;
+/*!50001 SET @saved_cs_results = @@character_set_results */;
+/*!50001 SET @saved_col_connection = @@collation_connection */;
+/*!50001 SET character_set_client = latin1 */;
+/*!50001 SET character_set_results = latin1 */;
+/*!50001 SET collation_connection = latin1_swedish_ci */;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v3ps` AS select `performance_schema`.`users`.`USER` AS `user` from `performance_schema`.`users` where `performance_schema`.`users`.`CURRENT_CONNECTIONS` > 0 order by `performance_schema`.`users`.`USER` */;
+/*!50001 SET character_set_client = @saved_cs_client */;
+/*!50001 SET character_set_results = @saved_cs_results */;
+/*!50001 SET collation_connection = @saved_col_connection */;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3 write;
+ERROR 42000: Access denied for user 'invoker'@'localhost' to database 'mysqltest3'
+disconnect inv;
+connection default;
+grant lock tables on mysqltest3.* to invoker@localhost;
+connect inv,localhost,invoker;
+show create view mysqltest3.v3;
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3` AS select `v2`.`a` AS `a` from `mysqltest2`.`v2` latin1 latin1_swedish_ci
+show create view mysqltest3.v3is;
+View Create View character_set_client collation_connection
+v3is CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3is` AS select `information_schema`.`schemata`.`SCHEMA_NAME` AS `schema_name` from `information_schema`.`schemata` order by `information_schema`.`schemata`.`SCHEMA_NAME` latin1 latin1_swedish_ci
+show create view mysqltest3.v3ps;
+View Create View character_set_client collation_connection
+v3ps CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3ps` AS select `performance_schema`.`users`.`USER` AS `user` from `performance_schema`.`users` where `performance_schema`.`users`.`CURRENT_CONNECTIONS` > 0 order by `performance_schema`.`users`.`USER` latin1 latin1_swedish_ci
+show create view mysqltest3.v3nt;
+View Create View character_set_client collation_connection
+v3nt CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3nt` AS select 1 AS `1` latin1 latin1_swedish_ci
+show create view mysqltest3.v3i;
+View Create View character_set_client collation_connection
+v3i CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY INVOKER VIEW `mysqltest3`.`v3i` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+lock table mysqltest3.v3 write;
+ERROR HY000: View 'mysqltest3.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+lock table mysqltest3.v3i write;
+ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+lock table mysqltest3.v3is write;
+select * from mysqltest3.v3is;
+schema_name
+information_schema
+mysqltest1
+mysqltest2
+performance_schema
+test
+lock table mysqltest3.v3ps write;
+select * from mysqltest3.v3ps;
+user
+NULL
+invoker
+root
+lock table mysqltest3.v3nt write;
+select * from mysqltest3.v3nt;
+1
+1
+disconnect inv;
+connection default;
+grant lock tables on mysqltest2.* to invoker@localhost;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3 write;
+ERROR HY000: View 'mysqltest3.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+lock table mysqltest3.v3i write;
+ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+disconnect inv;
+connection default;
+grant lock tables on mysqltest1.* to definer@localhost;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3 write;
+select * from mysqltest3.v3;
+a
+lock table mysqltest3.v3i write;
+ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+disconnect inv;
+connection default;
+grant lock tables on mysqltest1.* to invoker@localhost;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3i write;
+select * from mysqltest3.v3i;
+a
+disconnect inv;
+connection default;
+drop user invoker@localhost;
+drop user definer@localhost;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
diff --git a/mysql-test/main/lock_view.test b/mysql-test/main/lock_view.test
new file mode 100644
index 00000000000..dd8809ab89d
--- /dev/null
+++ b/mysql-test/main/lock_view.test
@@ -0,0 +1,76 @@
+source include/not_embedded.inc;
+#
+# LOCK TABLES and privileges on views
+#
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create user invoker@localhost;
+create user definer@localhost;
+grant select,show view on mysqltest1.* to invoker@localhost;
+grant select,show view on mysqltest1.* to definer@localhost;
+grant select,show view on mysqltest2.* to invoker@localhost;
+grant select,show view on mysqltest2.* to definer@localhost;
+grant select,show view on mysqltest3.* to invoker@localhost;
+grant select on performance_schema.* to definer@localhost;
+create table mysqltest1.t1 (a int);
+create definer=definer@localhost view mysqltest2.v2 as select * from mysqltest1.t1;
+create definer=definer@localhost view mysqltest3.v3 as select * from mysqltest2.v2;
+create definer=definer@localhost view mysqltest3.v3is as select schema_name from information_schema.schemata order by schema_name;
+create definer=definer@localhost view mysqltest3.v3ps as select user from performance_schema.users where current_connections>0 order by user;
+create definer=definer@localhost view mysqltest3.v3nt as select 1;
+create definer=definer@localhost sql security invoker view mysqltest3.v3i as select * from mysqltest1.t1;
+
+exec $MYSQL_DUMP --compact -B mysqltest1 mysqltest2 mysqltest3;
+
+connect inv,localhost,invoker;
+error ER_DBACCESS_DENIED_ERROR;
+lock table mysqltest3.v3 write;
+disconnect inv;
+connection default;
+
+grant lock tables on mysqltest3.* to invoker@localhost;
+connect inv,localhost,invoker;
+show create view mysqltest3.v3;
+show create view mysqltest3.v3is;
+show create view mysqltest3.v3ps;
+show create view mysqltest3.v3nt;
+show create view mysqltest3.v3i;
+error ER_VIEW_INVALID;
+lock table mysqltest3.v3 write;
+error ER_VIEW_INVALID;
+lock table mysqltest3.v3i write;
+lock table mysqltest3.v3is write; select * from mysqltest3.v3is;
+lock table mysqltest3.v3ps write; select * from mysqltest3.v3ps;
+lock table mysqltest3.v3nt write; select * from mysqltest3.v3nt;
+disconnect inv;
+connection default;
+
+grant lock tables on mysqltest2.* to invoker@localhost;
+connect inv,localhost,invoker;
+error ER_VIEW_INVALID;
+lock table mysqltest3.v3 write;
+error ER_VIEW_INVALID;
+lock table mysqltest3.v3i write;
+disconnect inv;
+connection default;
+
+grant lock tables on mysqltest1.* to definer@localhost;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3 write; select * from mysqltest3.v3;
+error ER_VIEW_INVALID;
+lock table mysqltest3.v3i write;
+disconnect inv;
+connection default;
+
+grant lock tables on mysqltest1.* to invoker@localhost;
+connect inv,localhost,invoker;
+lock table mysqltest3.v3i write; select * from mysqltest3.v3i;
+disconnect inv;
+connection default;
+
+drop user invoker@localhost;
+drop user definer@localhost;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
diff --git a/mysql-test/main/log_tables.result b/mysql-test/main/log_tables.result
index 90c97f629fb..914bc06748e 100644
--- a/mysql-test/main/log_tables.result
+++ b/mysql-test/main/log_tables.result
@@ -380,6 +380,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/main/log_tables.test b/mysql-test/main/log_tables.test
index ff2a46b1917..537bd843af8 100644
--- a/mysql-test/main/log_tables.test
+++ b/mysql-test/main/log_tables.test
@@ -54,7 +54,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
#
@@ -475,6 +475,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/main/multi_update_big.result b/mysql-test/main/multi_update_big.result
index 3712e638f40..746a158f21f 100644
--- a/mysql-test/main/multi_update_big.result
+++ b/mysql-test/main/multi_update_big.result
@@ -1,6 +1,5 @@
-DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL) ;
-# The protocolling of many inserts into t1 is suppressed.
+INSERT INTO t1 SELECT seq,seq FROM seq_1_to_2097152;
ALTER TABLE t1 ADD INDEX i1(a);
DELETE FROM t1 WHERE a > 2000000;
CREATE TABLE t2 LIKE t1;
diff --git a/mysql-test/main/multi_update_big.test b/mysql-test/main/multi_update_big.test
index a0f17fabec4..d6fec704822 100644
--- a/mysql-test/main/multi_update_big.test
+++ b/mysql-test/main/multi_update_big.test
@@ -1,4 +1,5 @@
--source include/long_test.inc
+--source include/have_sequence.inc
#
# Test of update statement that uses many tables.
@@ -40,25 +41,9 @@ if (`SELECT '$BIG_TEST' = '' AND $need_big = 1`)
# Bug#1820 Rows not deleted from second table on multi-table delete
#
---disable_warnings
-DROP TABLE IF EXISTS t1,t2;
---enable_warnings
-
CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL) ;
---echo # The protocolling of many inserts into t1 is suppressed.
---disable_query_log
-INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4);
-let $1=19;
-set @d=4;
-begin;
-while ($1)
-{
- eval INSERT INTO t1 SELECT a+@d,b+@d FROM t1;
- eval SET @d=@d*2;
- dec $1;
-}
-commit;
---enable_query_log
+INSERT INTO t1 SELECT seq,seq FROM seq_1_to_2097152;
+
ALTER TABLE t1 ADD INDEX i1(a);
DELETE FROM t1 WHERE a > 2000000;
CREATE TABLE t2 LIKE t1;
diff --git a/mysql-test/main/myisam_icp_debug.result b/mysql-test/main/myisam_icp_debug.result
new file mode 100644
index 00000000000..cb45a0e2274
--- /dev/null
+++ b/mysql-test/main/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/main/myisam_icp_debug.test b/mysql-test/main/myisam_icp_debug.test
new file mode 100644
index 00000000000..d5b1af799fa
--- /dev/null
+++ b/mysql-test/main/myisam_icp_debug.test
@@ -0,0 +1 @@
+--source include/icp_debug_kill.inc
diff --git a/mysql-test/main/mysql_json_table_recreate.opt b/mysql-test/main/mysql_json_table_recreate.opt
new file mode 100644
index 00000000000..135fd2b77b8
--- /dev/null
+++ b/mysql-test/main/mysql_json_table_recreate.opt
@@ -0,0 +1 @@
+--plugin-load=$TYPE_MYSQL_JSON_SO
diff --git a/mysql-test/main/mysql_json_table_recreate.result b/mysql-test/main/mysql_json_table_recreate.result
new file mode 100644
index 00000000000..3dfc6d7a259
--- /dev/null
+++ b/mysql-test/main/mysql_json_table_recreate.result
@@ -0,0 +1,171 @@
+#
+# The following test takes 2 tables containing a JSON column and attempts
+# to repair them.
+#
+# The tables header is (Description, Expected, Actual), where description
+# shows a brief description what the JSON value is testing in the MariaDB
+# implementation. Expected is the longtext string and actual is the JSON
+# column that needs to be converted to MariaDB's representation of
+# LONGTEXT.
+#
+call mtr.add_suppression("Table rebuild required");
+call mtr.add_suppression("is marked as crashed");
+call mtr.add_suppression("Checking");
+SET NAMES utf8;
+#
+# Check that only ALTER TABLE ... FORCE is allowed on a MySQL 5.7 table
+# with a JSON column.
+#
+show create table tempty;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it!
+select * from tempty;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it!
+alter table tempty force;
+show create table tempty;
+Table Create Table
+tempty CREATE TABLE `tempty` (
+ `t` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table mysql_json_test;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it!
+select * from mysql_json_test;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it!
+LOCK TABLES mysql_json_test WRITE;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it!
+alter table mysql_json_test force;
+select description, expected, actual, expected = actual from mysql_json_test;
+description expected actual expected = actual
+Array LITERALS: ["prefix", false, "suffix", 1] ["prefix", false, "suffix", 1] 1
+Array LITERALS: ["prefix", null, "suffix", 1] ["prefix", null, "suffix", 1] 1
+Array LITERALS: ["prefix", true, "suffix", 1] ["prefix", true, "suffix", 1] 1
+DateTime as Raw Value: "2015-01-15 23:24:25.000000" "2015-01-15 23:24:25.000000" 1
+DateTime as Raw Value: "2015-01-15 23:24:25.000000" "2015-01-15 23:24:25.000000" 1
+DateTime as Raw Value: "2015-01-15" "2015-01-15" 1
+DateTime as Raw Value: "23:24:25.000000" "23:24:25.000000" 1
+Empty JSON Object/Array: [] [] 1
+Empty JSON Object/Array: {} {} 1
+GeoJSON {"type": "GeometryCollection", "geometries": []} {"type": "GeometryCollection", "geometries": []} 1
+GeoJSON {"type": "LineString", "coordinates": [[0, 5], [5, 10], [10, 15]]} {"type": "LineString", "coordinates": [[0, 5], [5, 10], [10, 15]]} 1
+GeoJSON {"type": "MultiPoint", "coordinates": [[1, 1], [2, 2], [3, 3]]} {"type": "MultiPoint", "coordinates": [[1, 1], [2, 2], [3, 3]]} 1
+GeoJSON {"type": "Point", "coordinates": [11.1111, 12.22222]} {"type": "Point", "coordinates": [11.1111, 12.22222]} 1
+JSON LITERALS: {"val": false} {"val": false} 1
+JSON LITERALS: {"val": null} {"val": null} 1
+JSON LITERALS: {"val": true} {"val": true} 1
+Opaque Types: opaque_mysql_type_binary "base64:type254:YWJjAAAAAAAAAA==" "base64:type254:YWJjAAAAAAAAAA==" 1
+Opaque Types: opaque_mysql_type_bit "base64:type16:yv4=" "base64:type16:yv4=" 1
+Opaque Types: opaque_mysql_type_blob "base64:type252:yv66vg==" "base64:type252:yv66vg==" 1
+Opaque Types: opaque_mysql_type_date "2015-01-15" "2015-01-15" 1
+Opaque Types: opaque_mysql_type_datetime "2015-01-15 23:24:25.000000" "2015-01-15 23:24:25.000000" 1
+Opaque Types: opaque_mysql_type_enum "b" "b" 1
+Opaque Types: opaque_mysql_type_geom {"type": "Point", "coordinates": [1, 1]} {"type": "Point", "coordinates": [1, 1]} 1
+Opaque Types: opaque_mysql_type_longblob "base64:type251:yv66vg==" "base64:type251:yv66vg==" 1
+Opaque Types: opaque_mysql_type_mediumblob "base64:type250:yv66vg==" "base64:type250:yv66vg==" 1
+Opaque Types: opaque_mysql_type_set "b,c" "b,c" 1
+Opaque Types: opaque_mysql_type_time "23:24:25.000000" "23:24:25.000000" 1
+Opaque Types: opaque_mysql_type_tinyblob "base64:type249:yv66vg==" "base64:type249:yv66vg==" 1
+Opaque Types: opaque_mysql_type_varbinary "base64:type15:YWJj" "base64:type15:YWJj" 1
+Opaque Types: opaque_mysql_type_varchar "base64:type15:Zm9v" "base64:type15:Zm9v" 1
+Opaque Types: opaque_mysql_type_year "base64:type13:MjAxOQ==" "base64:type13:MjAxOQ==" 1
+Raw LITERALS: false false 1
+Raw LITERALS: null null 1
+Raw LITERALS: true true 1
+Raw doubles as JSON -2.2250738585072014e-308 -2.2250738585072014e-308 1
+Raw doubles as JSON -5678.987 -5678.987 1
+Raw doubles as JSON 0.0 0.0 1
+Raw doubles as JSON 2.2250738585072014e-308 2.2250738585072014e-308 1
+Raw doubles as JSON 3.14 3.14 1
+Raw integers as JSON -127 -127 1
+Raw integers as JSON -2147483648 -2147483648 1
+Raw integers as JSON -32768 -32768 1
+Raw integers as JSON -9223372036854775807 -9223372036854775807 1
+Raw integers as JSON 0 0 1
+Raw integers as JSON 128 128 1
+Raw integers as JSON 18446744073709551615 18446744073709551615 1
+Raw integers as JSON 2147483647 2147483647 1
+Raw integers as JSON 32767 32767 1
+Raw integers as JSON 4294967295 4294967295 1
+Raw integers as JSON 65535 65535 1
+Raw integers as JSON 65536 65536 1
+Raw integers as JSON 9223372036854775807 9223372036854775807 1
+Simple Array as Base Key [1, 2, 3, 4, 5, [], "a", "b", "c"] [1, 2, 3, 4, 5, [], "a", "b", "c"] 1
+Simple Array as Value {"a": [1, 2], "b": ["x", "y"]} {"a": [1, 2], "b": ["x", "y"]} 1
+Simple JSON test {"key1": "val1", "key2": "val2"} {"key1": "val1", "key2": "val2"} 1
+Special Characters: "" "" 1
+Special Characters: "'" "'" 1
+Special Characters: "'" "'" 1
+Special Characters: "'" "'" 1
+Special Characters: "''" "''" 1
+Special Characters: "\"" "\"" 1
+Special Characters: "\\" "\\" 1
+Special Characters: "\\b" "\\b" 1
+Special Characters: "\b" "\b" 1
+Special Characters: "\f" "\f" 1
+Special Characters: "\n" "\n" 1
+Special Characters: "\r" "\r" 1
+Special Characters: "\t" "\t" 1
+Special Characters: "f" "f" 1
+Special Characters: "key1 - with \" val " "key1 - with \" val " 1
+Special Characters: "q" "q" 1
+Special Characters: "some_string" "some_string" 1
+Special Characters: ["a ' b", "c ' d"] ["a ' b", "c ' d"] 1
+Special Characters: ["a \" b", "c \" d"] ["a \" b", "c \" d"] 1
+Special Characters: ["a \\ b", "c \\ d"] ["a \\ b", "c \\ d"] 1
+Special Characters: ["a \b b", "c \b d"] ["a \b b", "c \b d"] 1
+Special Characters: ["a \f b", "c \f d"] ["a \f b", "c \f d"] 1
+Special Characters: ["a \r b", "c \r d"] ["a \r b", "c \r d"] 1
+Special Characters: ["a \t b", "c \t d"] ["a \t b", "c \t d"] 1
+Special Characters: {"[": "]"} {"[": "]"} 1
+Special Characters: {"key ' key": "val ' val"} {"key ' key": "val ' val"} 1
+Special Characters: {"key \" key": "val \" val"} {"key \" key": "val \" val"} 1
+Special Characters: {"key \\ key": "val \\ val"} {"key \\ key": "val \\ val"} 1
+Special Characters: {"key \\0 key": "val \n val"} {"key \\0 key": "val \n val"} 1
+Special Characters: {"key \\Z key": "val ' val"} {"key \\Z key": "val ' val"} 1
+Special Characters: {"key \b key": "val \b val"} {"key \b key": "val \b val"} 1
+Special Characters: {"key \f key": "val \f val"} {"key \f key": "val \f val"} 1
+Special Characters: {"key \n key": "val \n val"} {"key \n key": "val \n val"} 1
+Special Characters: {"key \r key": "val \r val"} {"key \r key": "val \r val"} 1
+Special Characters: {"key \t key": "val \t val"} {"key \t key": "val \t val"} 1
+Special Characters: {"key1 and \n\"key2\"": "val1\t val2"} {"key1 and \n\"key2\"": "val1\t val2"} 1
+Special Characters: {"{": "}"} {"{": "}"} 1
+Special Characters: {"{": "}"} {"{": "}"} 1
+Special String Cases: [""] [""] 1
+Special String Cases: {"": ""} {"": ""} 1
+Timestamp as RawValue "2019-12-26 19:56:03.000000" "2019-12-26 19:56:03.000000" 1
+UTF8 Characters: "Anel Husaković - test: đžšćÄ" "Anel Husaković - test: đžšćÄ" 1
+UTF8 Characters: {"Name": "Anel Husaković - test: đžšćÄ"} {"Name": "Anel Husaković - test: đžšćÄ"} 1
+UTF8 Characters: {"Person": "EMP", "details": {"Name": "Anel Husaković - test: đžšćÄ"}} {"Person": "EMP", "details": {"Name": "Anel Husaković - test: đžšćÄ"}} 1
+UTF8 Characters: {"details": {"Name": "Anel Husaković - test: đžšćÄ"}, "\"Anel Husaković - test: đžšćÄ\"": "EMP"} {"details": {"Name": "Anel Husaković - test: đžšćÄ"}, "\"Anel Husaković - test: đžšćÄ\"": "EMP"} 1
+#
+# A quick check that all rows match from the original MySQL Table.
+#
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests'
+from mysql_json_test;
+Total_Number_of_Tests Succesful_Tests
+100 100
+show create table mysql_json_test;
+Table Create Table
+mysql_json_test CREATE TABLE `mysql_json_test` (
+ `description` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `expected` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `actual` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
+show create table mysql_json_test_big;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it!
+select * from mysql_json_test_big;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it!
+#
+# This test checks the long format implementation of MySQL's JSON
+# Not printing the actual contents as they are not readable by a human,
+# just compare the strings, make sure they match.
+#
+alter table mysql_json_test_big force;
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests',
+sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test_big;
+Total_Number_of_Tests Succesful_Tests String_is_valid_JSON
+1 1 1
+drop table tempty;
+drop table mysql_json_test;
+drop table mysql_json_test_big;
diff --git a/mysql-test/main/mysql_json_table_recreate.test b/mysql-test/main/mysql_json_table_recreate.test
new file mode 100644
index 00000000000..de1e9202985
--- /dev/null
+++ b/mysql-test/main/mysql_json_table_recreate.test
@@ -0,0 +1,93 @@
+--source include/have_utf8.inc
+
+if (!$TYPE_MYSQL_JSON_SO) {
+ skip Need MYSQL_JSON plugin;
+}
+
+--echo #
+--echo # The following test takes 2 tables containing a JSON column and attempts
+--echo # to repair them.
+--echo #
+--echo # The tables header is (Description, Expected, Actual), where description
+--echo # shows a brief description what the JSON value is testing in the MariaDB
+--echo # implementation. Expected is the longtext string and actual is the JSON
+--echo # column that needs to be converted to MariaDB's representation of
+--echo # LONGTEXT.
+--echo #
+
+
+call mtr.add_suppression("Table rebuild required");
+call mtr.add_suppression("is marked as crashed");
+call mtr.add_suppression("Checking");
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+SET NAMES utf8;
+
+--copy_file std_data/mysql_json/tempty.frm $MYSQLD_DATADIR/test/tempty.frm
+--copy_file std_data/mysql_json/tempty.MYI $MYSQLD_DATADIR/test/tempty.MYI
+--copy_file std_data/mysql_json/tempty.MYD $MYSQLD_DATADIR/test/tempty.MYD
+
+--copy_file std_data/mysql_json/mysql_json_test.frm $MYSQLD_DATADIR/test/mysql_json_test.frm
+--copy_file std_data/mysql_json/mysql_json_test.MYI $MYSQLD_DATADIR/test/mysql_json_test.MYI
+--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/test/mysql_json_test.MYD
+
+--copy_file std_data/mysql_json/mysql_json_test_big.frm $MYSQLD_DATADIR/test/mysql_json_test_big.frm
+--copy_file std_data/mysql_json/mysql_json_test_big.MYI $MYSQLD_DATADIR/test/mysql_json_test_big.MYI
+--copy_file std_data/mysql_json/mysql_json_test_big.MYD $MYSQLD_DATADIR/test/mysql_json_test_big.MYD
+
+--echo #
+--echo # Check that only ALTER TABLE ... FORCE is allowed on a MySQL 5.7 table
+--echo # with a JSON column.
+--echo #
+
+--error ER_TABLE_NEEDS_REBUILD
+show create table tempty;
+--error ER_TABLE_NEEDS_REBUILD
+select * from tempty;
+
+alter table tempty force;
+show create table tempty;
+
+--error ER_TABLE_NEEDS_REBUILD
+show create table mysql_json_test;
+--error ER_TABLE_NEEDS_REBUILD
+select * from mysql_json_test;
+
+--error ER_TABLE_NEEDS_REBUILD
+LOCK TABLES mysql_json_test WRITE;
+
+alter table mysql_json_test force;
+
+--sorted_result
+select description, expected, actual, expected = actual from mysql_json_test;
+
+--echo #
+--echo # A quick check that all rows match from the original MySQL Table.
+--echo #
+select count(*) as 'Total_Number_of_Tests',
+ sum(expected = actual) as 'Succesful_Tests'
+from mysql_json_test;
+
+show create table mysql_json_test;
+
+--error ER_TABLE_NEEDS_REBUILD
+show create table mysql_json_test_big;
+--error ER_TABLE_NEEDS_REBUILD
+select * from mysql_json_test_big;
+
+--echo #
+--echo # This test checks the long format implementation of MySQL's JSON
+--echo # Not printing the actual contents as they are not readable by a human,
+--echo # just compare the strings, make sure they match.
+--echo #
+alter table mysql_json_test_big force;
+
+select count(*) as 'Total_Number_of_Tests',
+ sum(expected = actual) as 'Succesful_Tests',
+ sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test_big;
+
+drop table tempty;
+drop table mysql_json_test;
+drop table mysql_json_test_big;
diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result
index d41df55b113..539fe19f072 100644
--- a/mysql-test/main/mysql_upgrade.result
+++ b/mysql-test/main/mysql_upgrade.result
@@ -145,7 +145,7 @@ test
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK
DROP USER mysqltest1@'%';
-Version check failed. Got the following error when calling the 'mysql_upgrade' command line client
+Version check failed. Got the following error when calling the 'mysql' command line client
ERROR 1045 (28000): Access denied for user 'mysqltest1'@'localhost' (using password: YES)
FATAL ERROR: Upgrade failed
Run mysql_upgrade with a non existing server socket
@@ -412,7 +412,7 @@ OK
# Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR
#
Run mysql_upgrade with unauthorized access
-Version check failed. Got the following error when calling the 'mysql_upgrade' command line client
+Version check failed. Got the following error when calling the 'mysql' command line client
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
FATAL ERROR: Upgrade failed
#
@@ -570,6 +570,128 @@ t1 CREATE TABLE `t1` (
DROP TABLE test.t1;
SET GLOBAL enforce_storage_engine=NULL;
# End of 10.1 tests
+#
+# MDEV-23201 'Roles' are created incorrectly on an install that was previously MySQL 5.7
+#
+#
+DROP VIEW mysql.user;
+FLUSH TABLES mysql.user;
+FLUSH PRIVILEGES;
+SHOW CREATE TABLE mysql.user;
+Table Create Table
+user CREATE TABLE `user` (
+ `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
+ `User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
+ `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
+ `ssl_cipher` blob NOT NULL,
+ `x509_issuer` blob NOT NULL,
+ `x509_subject` blob NOT NULL,
+ `max_questions` int(11) unsigned NOT NULL DEFAULT 0,
+ `max_updates` int(11) unsigned NOT NULL DEFAULT 0,
+ `max_connections` int(11) unsigned NOT NULL DEFAULT 0,
+ `max_user_connections` int(11) unsigned NOT NULL DEFAULT 0,
+ `plugin` char(64) COLLATE utf8_bin NOT NULL DEFAULT 'mysql_native_password',
+ `authentication_string` text COLLATE utf8_bin DEFAULT NULL,
+ `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ `password_last_changed` timestamp NULL DEFAULT NULL,
+ `password_lifetime` smallint(5) unsigned DEFAULT NULL,
+ `account_locked` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
+ PRIMARY KEY (`Host`,`User`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
+Phase 1/7: Checking and upgrading mysql database
+Processing databases
+mysql
+mysql.column_stats OK
+mysql.columns_priv OK
+mysql.db OK
+mysql.event OK
+mysql.func OK
+mysql.global_priv OK
+mysql.gtid_slave_pos OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.index_stats OK
+mysql.innodb_index_stats OK
+mysql.innodb_table_stats OK
+mysql.plugin OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.proxies_priv OK
+mysql.roles_mapping OK
+mysql.servers OK
+mysql.table_stats OK
+mysql.tables_priv OK
+mysql.time_zone OK
+mysql.time_zone_leap_second OK
+mysql.time_zone_name OK
+mysql.time_zone_transition OK
+mysql.time_zone_transition_type OK
+mysql.transaction_registry OK
+mysql.user OK
+Upgrading from a version before MariaDB-10.1
+Phase 2/7: Installing used storage engines
+Checking for tables with unknown storage engine
+Phase 3/7: Fixing views
+Phase 4/7: Running 'mysql_fix_privilege_tables'
+Phase 5/7: Fixing table and database names
+Phase 6/7: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
+mtr.global_suppressions OK
+mtr.test_suppressions OK
+performance_schema
+test
+Phase 7/7: Running 'FLUSH PRIVILEGES'
+OK
+SHOW CREATE TABLE mysql.user;
+View Create View character_set_client collation_connection
+user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `mysql`.`user` AS select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` latin1 latin1_swedish_ci
+CREATE ROLE `aRole`;
+SET ROLE `aRole`;
+FLUSH PRIVILEGES;
+SET ROLE `aRole`;
+SELECT `User`, `is_role` FROM `mysql`.`user`;
+User is_role
+mariadb.sys N
+root N
+root N
+root N
+root N
+aRole Y
+DROP ROLE `aRole`;
+FLUSH PRIVILEGES;
# End of 10.2 tests
#
# Ensure that mysql_upgrade correctly sets truncate_versioning_priv
diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test
index 42c4a545dd7..a6345af937d 100644
--- a/mysql-test/main/mysql_upgrade.test
+++ b/mysql-test/main/mysql_upgrade.test
@@ -219,6 +219,37 @@ SET GLOBAL enforce_storage_engine=NULL;
--echo # End of 10.1 tests
+--echo #
+--echo # MDEV-23201 'Roles' are created incorrectly on an install that was previously MySQL 5.7
+--echo #
+--echo #
+
+--exec $MYSQL_DUMP --result-file $MYSQLTEST_VARDIR/tmp/user.sql mysql user
+DROP VIEW mysql.user;
+
+--copy_file std_data/mysql57user.frm $MYSQLD_DATADIR/mysql/user.frm
+--copy_file std_data/mysql57user.MYI $MYSQLD_DATADIR/mysql/user.MYI
+--copy_file std_data/mysql57user.MYD $MYSQLD_DATADIR/mysql/user.MYD
+FLUSH TABLES mysql.user;
+FLUSH PRIVILEGES;
+SHOW CREATE TABLE mysql.user;
+
+--exec $MYSQL_UPGRADE --force 2>&1
+SHOW CREATE TABLE mysql.user;
+
+CREATE ROLE `aRole`;
+SET ROLE `aRole`;
+
+FLUSH PRIVILEGES;
+
+SET ROLE `aRole`;
+SELECT `User`, `is_role` FROM `mysql`.`user`;
+
+DROP ROLE `aRole`;
+--exec $MYSQL mysql < $MYSQLTEST_VARDIR/tmp/user.sql
+FLUSH PRIVILEGES;
+--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
+
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/mysql_upgrade_mysql_json_datatype.result b/mysql-test/main/mysql_upgrade_mysql_json_datatype.result
new file mode 100644
index 00000000000..604ef2bc0df
--- /dev/null
+++ b/mysql-test/main/mysql_upgrade_mysql_json_datatype.result
@@ -0,0 +1,106 @@
+call mtr.add_suppression("Table rebuild required");
+call mtr.add_suppression("is marked as crashed");
+call mtr.add_suppression("Checking");
+SET NAMES utf8;
+set sql_mode="";
+install soname 'type_mysql_json';
+show create table tempty;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it!
+show create table mysql_json_test;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it!
+show create table mysql_json_test_big;
+ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it!
+# Run mysql_upgrade to fix the tables containing JSON.
+Phase 1/7: Checking and upgrading mysql database
+Processing databases
+mysql
+mysql.column_stats OK
+mysql.columns_priv OK
+mysql.db OK
+mysql.event OK
+mysql.func OK
+mysql.global_priv OK
+mysql.gtid_slave_pos OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.index_stats OK
+mysql.innodb_index_stats OK
+mysql.innodb_table_stats OK
+mysql.plugin OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.proxies_priv OK
+mysql.roles_mapping OK
+mysql.servers OK
+mysql.table_stats OK
+mysql.tables_priv OK
+mysql.time_zone OK
+mysql.time_zone_leap_second OK
+mysql.time_zone_name OK
+mysql.time_zone_transition OK
+mysql.time_zone_transition_type OK
+mysql.transaction_registry OK
+Phase 2/7: Installing used storage engines... Skipped
+Phase 3/7: Fixing views
+mysql.user OK
+Phase 4/7: Running 'mysql_fix_privilege_tables'
+Phase 5/7: Fixing table and database names
+Phase 6/7: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
+mtr.global_suppressions OK
+mtr.test_suppressions OK
+performance_schema
+test
+test.mysql_json_test Needs upgrade
+test.mysql_json_test_big Needs upgrade
+test.tempty Needs upgrade
+
+Repairing tables
+test.mysql_json_test OK
+test.mysql_json_test_big OK
+test.tempty OK
+Phase 7/7: Running 'FLUSH PRIVILEGES'
+OK
+#
+# Now check if the table structure is correct and that the data
+# is still present.
+#
+show create table tempty;
+Table Create Table
+tempty CREATE TABLE `tempty` (
+ `t` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table mysql_json_test;
+Table Create Table
+mysql_json_test CREATE TABLE `mysql_json_test` (
+ `description` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `expected` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `actual` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
+show create table mysql_json_test_big;
+Table Create Table
+mysql_json_test_big CREATE TABLE `mysql_json_test_big` (
+ `description` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `expected` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `actual` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests',
+sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test;
+Total_Number_of_Tests Succesful_Tests String_is_valid_JSON
+100 100 100
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests',
+sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test_big;
+Total_Number_of_Tests Succesful_Tests String_is_valid_JSON
+1 1 1
+drop table tempty;
+drop table mysql_json_test;
+drop table mysql_json_test_big;
+uninstall soname 'type_mysql_json';
diff --git a/mysql-test/main/mysql_upgrade_mysql_json_datatype.test b/mysql-test/main/mysql_upgrade_mysql_json_datatype.test
new file mode 100644
index 00000000000..0363b2d0dc1
--- /dev/null
+++ b/mysql-test/main/mysql_upgrade_mysql_json_datatype.test
@@ -0,0 +1,67 @@
+-- source include/mysql_upgrade_preparation.inc
+-- source include/have_working_dns.inc
+-- source include/have_innodb.inc
+
+if (!$TYPE_MYSQL_JSON_SO) {
+ skip Need MYSQL_JSON plugin;
+}
+
+call mtr.add_suppression("Table rebuild required");
+call mtr.add_suppression("is marked as crashed");
+call mtr.add_suppression("Checking");
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+SET NAMES utf8;
+
+--copy_file std_data/mysql_json/tempty.frm $MYSQLD_DATADIR/test/tempty.frm
+--copy_file std_data/mysql_json/tempty.MYI $MYSQLD_DATADIR/test/tempty.MYI
+--copy_file std_data/mysql_json/tempty.MYD $MYSQLD_DATADIR/test/tempty.MYD
+
+--copy_file std_data/mysql_json/mysql_json_test.frm $MYSQLD_DATADIR/test/mysql_json_test.frm
+--copy_file std_data/mysql_json/mysql_json_test.MYI $MYSQLD_DATADIR/test/mysql_json_test.MYI
+--copy_file std_data/mysql_json/mysql_json_test.MYD $MYSQLD_DATADIR/test/mysql_json_test.MYD
+
+--copy_file std_data/mysql_json/mysql_json_test_big.frm $MYSQLD_DATADIR/test/mysql_json_test_big.frm
+--copy_file std_data/mysql_json/mysql_json_test_big.MYI $MYSQLD_DATADIR/test/mysql_json_test_big.MYI
+--copy_file std_data/mysql_json/mysql_json_test_big.MYD $MYSQLD_DATADIR/test/mysql_json_test_big.MYD
+
+
+set sql_mode="";
+
+install soname 'type_mysql_json';
+
+--error ER_TABLE_NEEDS_REBUILD
+show create table tempty;
+--error ER_TABLE_NEEDS_REBUILD
+show create table mysql_json_test;
+--error ER_TABLE_NEEDS_REBUILD
+show create table mysql_json_test_big;
+
+--echo # Run mysql_upgrade to fix the tables containing JSON.
+--exec $MYSQL_UPGRADE --force 2>&1
+
+--echo #
+--echo # Now check if the table structure is correct and that the data
+--echo # is still present.
+--echo #
+
+show create table tempty;
+show create table mysql_json_test;
+show create table mysql_json_test_big;
+
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests',
+sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test;
+
+select count(*) as 'Total_Number_of_Tests',
+sum(expected = actual) as 'Succesful_Tests',
+sum(JSON_VALID(actual)) as 'String_is_valid_JSON'
+from mysql_json_test_big;
+
+drop table tempty;
+drop table mysql_json_test;
+drop table mysql_json_test_big;
+
+uninstall soname 'type_mysql_json';
+--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result
index 3b7d95f80e9..a263b81a28c 100644
--- a/mysql-test/main/mysqldump.result
+++ b/mysql-test/main/mysqldump.result
@@ -5905,4 +5905,122 @@ invisible int(11) YES NULL
a b c & $!@#$%^&*( ) int(11) YES 4 INVISIBLE
ds=~!@ \# $% ^ & * ( ) _ - = + int(11) YES 5 INVISIBLE
drop database d;
+#
+# MDEV-21786:
+# mysqldump will forget sequence definition details on --no-data dump
+#
+create database d;
+CREATE SEQUENCE d.s1 START WITH 100 INCREMENT BY 10 MINVALUE=100 MAXVALUE=1100 CYCLE;
+CREATE SEQUENCE d.s2 START WITH 200 INCREMENT BY 20 MINVALUE=200 MAXVALUE=1200 CYCLE;
+CREATE SEQUENCE d.s3 START WITH 300 INCREMENT BY 30 MINVALUE=300 MAXVALUE=1300 CYCLE;
+CREATE SEQUENCE d.s4 START WITH 400 INCREMENT BY 40 MINVALUE=400 MAXVALUE=1400 CYCLE;
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+NEXTVAL(d.s1) NEXTVAL(d.s2) NEXTVAL(d.s3) NEXTVAL(d.s4)
+100 200 300 400
+# Show create before dump
+show create sequence d.s1;
+Table Create Table
+s1 CREATE SEQUENCE `s1` start with 100 minvalue 100 maxvalue 1100 increment by 10 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s2;
+Table Create Table
+s2 CREATE SEQUENCE `s2` start with 200 minvalue 200 maxvalue 1200 increment by 20 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s3;
+Table Create Table
+s3 CREATE SEQUENCE `s3` start with 300 minvalue 300 maxvalue 1300 increment by 30 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s4;
+Table Create Table
+s4 CREATE SEQUENCE `s4` start with 400 minvalue 400 maxvalue 1400 increment by 40 cache 1000 cycle ENGINE=MyISAM
+# Dump sequence without `--no-data`
+# Restore from mysqldump
+SETVAL(`s1`, 1101, 0)
+1101
+SETVAL(`s2`, 1201, 0)
+1201
+SETVAL(`s3`, 1301, 0)
+1301
+SETVAL(`s4`, 1401, 0)
+1401
+# Show create after restore
+show create sequence d.s1;
+Table Create Table
+s1 CREATE SEQUENCE `s1` start with 100 minvalue 100 maxvalue 1100 increment by 10 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s2;
+Table Create Table
+s2 CREATE SEQUENCE `s2` start with 200 minvalue 200 maxvalue 1200 increment by 20 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s3;
+Table Create Table
+s3 CREATE SEQUENCE `s3` start with 300 minvalue 300 maxvalue 1300 increment by 30 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s4;
+Table Create Table
+s4 CREATE SEQUENCE `s4` start with 400 minvalue 400 maxvalue 1400 increment by 40 cache 1000 cycle ENGINE=MyISAM
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+NEXTVAL(d.s1) NEXTVAL(d.s2) NEXTVAL(d.s3) NEXTVAL(d.s4)
+100 200 300 400
+# Dump sequence with `--no-data`
+# Restore from mysqldump
+SETVAL(`s1`, 1101, 0)
+1101
+SETVAL(`s2`, 1201, 0)
+1201
+SETVAL(`s3`, 1301, 0)
+1301
+SETVAL(`s4`, 1401, 0)
+1401
+# Show create after restore `--no-data`
+show create sequence d.s1;
+Table Create Table
+s1 CREATE SEQUENCE `s1` start with 100 minvalue 100 maxvalue 1100 increment by 10 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s2;
+Table Create Table
+s2 CREATE SEQUENCE `s2` start with 200 minvalue 200 maxvalue 1200 increment by 20 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s3;
+Table Create Table
+s3 CREATE SEQUENCE `s3` start with 300 minvalue 300 maxvalue 1300 increment by 30 cache 1000 cycle ENGINE=MyISAM
+show create sequence d.s4;
+Table Create Table
+s4 CREATE SEQUENCE `s4` start with 400 minvalue 400 maxvalue 1400 increment by 40 cache 1000 cycle ENGINE=MyISAM
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+NEXTVAL(d.s1) NEXTVAL(d.s2) NEXTVAL(d.s3) NEXTVAL(d.s4)
+100 200 300 400
+# Restore to different database than original
+create database d2;
+SETVAL(`s1`, 1101, 0)
+1101
+SETVAL(`s2`, 1201, 0)
+1201
+SETVAL(`s3`, 1301, 0)
+1301
+SETVAL(`s4`, 1401, 0)
+1401
+show create sequence d2.s1;
+Table Create Table
+s1 CREATE SEQUENCE `s1` start with 100 minvalue 100 maxvalue 1100 increment by 10 cache 1000 cycle ENGINE=MyISAM
+drop sequence d.s1, d.s2, d.s3, d.s4;
+drop database d;
+drop database d2;
+#
+# MDEV-20070
+# mysqldump won't work correct on sequences
+#
+DROP DATABASE IF EXISTS test1;
+Warnings:
+Note 1008 Can't drop database 'test1'; database doesn't exist
+DROP DATABASE IF EXISTS test2;
+Warnings:
+Note 1008 Can't drop database 'test2'; database doesn't exist
+CREATE DATABASE test1;
+CREATE DATABASE test2;
+USE test1;
+CREATE SEQUENCE seq_t_i INCREMENT 5 START WITH 1;
+CREATE TABLE t(
+i integer DEFAULT nextval(seq_t_i),
+j integer
+);
+INSERT INTO t VALUES (1,1),(2,2),(3,3),(4,4);
+# Dump database 1
+# Restore from database 1 to database 2
+SETVAL(`seq_t_i`, 1, 0)
+1
+DROP DATABASE IF EXISTS test1;
+DROP DATABASE IF EXISTS test2;
# End of 10.3 tests
diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test
index 3f8777b9d48..f328bf32361 100644
--- a/mysql-test/main/mysqldump.test
+++ b/mysql-test/main/mysqldump.test
@@ -2793,4 +2793,87 @@ select * from t3;
desc t3;
drop database d;
+--echo #
+--echo # MDEV-21786:
+--echo # mysqldump will forget sequence definition details on --no-data dump
+--echo #
+create database d;
+
+CREATE SEQUENCE d.s1 START WITH 100 INCREMENT BY 10 MINVALUE=100 MAXVALUE=1100 CYCLE;
+CREATE SEQUENCE d.s2 START WITH 200 INCREMENT BY 20 MINVALUE=200 MAXVALUE=1200 CYCLE;
+CREATE SEQUENCE d.s3 START WITH 300 INCREMENT BY 30 MINVALUE=300 MAXVALUE=1300 CYCLE;
+CREATE SEQUENCE d.s4 START WITH 400 INCREMENT BY 40 MINVALUE=400 MAXVALUE=1400 CYCLE;
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+
+--echo # Show create before dump
+show create sequence d.s1;
+show create sequence d.s2;
+show create sequence d.s3;
+show create sequence d.s4;
+
+--echo # Dump sequence without `--no-data`
+--exec $MYSQL_DUMP --databases d > $MYSQLTEST_VARDIR/tmp/dump1.sql
+--echo # Restore from mysqldump
+--exec $MYSQL -Dd < $MYSQLTEST_VARDIR/tmp/dump1.sql
+--remove_file $MYSQLTEST_VARDIR/tmp/dump1.sql
+
+--echo # Show create after restore
+show create sequence d.s1;
+show create sequence d.s2;
+show create sequence d.s3;
+show create sequence d.s4;
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+
+--echo # Dump sequence with `--no-data`
+--exec $MYSQL_DUMP --databases d --no-data > $MYSQLTEST_VARDIR/tmp/dump-no-data.sql
+--echo # Restore from mysqldump
+--exec $MYSQL -Dd < $MYSQLTEST_VARDIR/tmp/dump-no-data.sql
+--remove_file $MYSQLTEST_VARDIR/tmp/dump-no-data.sql
+
+--echo # Show create after restore `--no-data`
+show create sequence d.s1;
+show create sequence d.s2;
+show create sequence d.s3;
+show create sequence d.s4;
+SELECT NEXTVAL(d.s1),NEXTVAL(d.s2),NEXTVAL(d.s3), NEXTVAL(d.s4);
+
+--echo # Restore to different database than original
+--exec $MYSQL_DUMP d > $MYSQLTEST_VARDIR/tmp/dumpd.sql
+create database d2;
+--exec $MYSQL d2 < $MYSQLTEST_VARDIR/tmp/dumpd.sql
+--remove_file $MYSQLTEST_VARDIR/tmp/dumpd.sql
+show create sequence d2.s1;
+
+drop sequence d.s1, d.s2, d.s3, d.s4;
+drop database d;
+drop database d2;
+
+--echo #
+--echo # MDEV-20070
+--echo # mysqldump won't work correct on sequences
+--echo #
+
+DROP DATABASE IF EXISTS test1;
+DROP DATABASE IF EXISTS test2;
+CREATE DATABASE test1;
+CREATE DATABASE test2;
+USE test1;
+CREATE SEQUENCE seq_t_i INCREMENT 5 START WITH 1;
+CREATE TABLE t(
+i integer DEFAULT nextval(seq_t_i),
+j integer
+);
+INSERT INTO t VALUES (1,1),(2,2),(3,3),(4,4);
+
+--echo # Dump database 1
+--exec $MYSQL_DUMP test1 > $MYSQLTEST_VARDIR/tmp/dumptest1.sql
+--echo # Restore from database 1 to database 2
+
+--error 1
+--exec $MYSQL test2 < $MYSQLTEST_VARDIR/tmp/dumptest1.sql
+
+--remove_file $MYSQLTEST_VARDIR/tmp/dumptest1.sql
+DROP DATABASE IF EXISTS test1;
+DROP DATABASE IF EXISTS test2;
+
--echo # End of 10.3 tests
diff --git a/mysql-test/main/opt_trace_index_merge_innodb.result b/mysql-test/main/opt_trace_index_merge_innodb.result
index 25e7b187104..509569021a5 100644
--- a/mysql-test/main/opt_trace_index_merge_innodb.result
+++ b/mysql-test/main/opt_trace_index_merge_innodb.result
@@ -117,7 +117,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 {
"using_mrr": false,
"index_only": false,
"rows": 1000,
- "cost": 201.6536043,
+ "cost": 204.27,
"chosen": true
},
{
@@ -137,8 +137,8 @@ explain select * from t1 where pk1 != 0 and key1 = 1 {
"index": "key1",
"index_scan_cost": 1.000146475,
"cumulated_index_scan_cost": 1.000146475,
- "disk_sweep_cost": 1.001383604,
- "cumulative_total_cost": 2.00153008,
+ "disk_sweep_cost": 1.004153686,
+ "cumulative_total_cost": 2.004300162,
"usable": true,
"matching_rows_now": 1,
"intersect_covering_with_this_index": false,
diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result
index 29a31a9c28c..603c852909f 100644
--- a/mysql-test/main/order_by.result
+++ b/mysql-test/main/order_by.result
@@ -3509,6 +3509,26 @@ NULLIF(GROUP_CONCAT(v1), null)
C
B
DROP TABLE t1;
+#
+# MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare
+#
+SET @save_max_length_for_sort_data=@@max_length_for_sort_data;
+SET @save_max_sort_length= @@max_sort_length;
+SET @save_sql_select_limit= @@sql_select_limit;
+CREATE TABLE t1 (a DECIMAL(64,0), b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+SET max_length_for_sort_data= 30;
+SET sql_select_limit = 3;
+SET max_sort_length=8;
+SELECT * FROM t1 ORDER BY a+1;
+a b
+1 1
+2 2
+3 3
+SET max_length_for_sort_data=@save_max_length_for_sort_data;
+SET max_sort_length= @save_max_sort_length;
+SET sql_select_limit= @save_sql_select_limit;
+DROP TABLE t1;
# End of 10.2 tests
#
# MDEV-16214: Incorrect plan taken by the optimizer , uses INDEX instead of ref access with ORDER BY
@@ -4123,6 +4143,127 @@ f
baz
foo
DROP TABLE t1;
+#
+# MDEV-24015: SQL Error (1038): Out of sort memory when enough memory for the
+# sort buffer is provided
+#
+CREATE TABLE t1 (a VARCHAR(100), b INT);
+CREATE TABLE t2 (a VARCHAR(100), b INT);
+INSERT INTO t1 SELECT 'abc', seq FROM seq_1_to_50;
+INSERT INTO t2 SELECT seq, seq FROM seq_1_to_50;
+set @save_sort_buffer_size= @@sort_buffer_size;
+set sort_buffer_size=2000;
+ANALYZE FORMAT=JSON
+SELECT (SELECT sum(t2.b) FROM t2 WHERE t1.b=t2.b GROUP BY t2.a) FROM t1;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 50,
+ "r_rows": 50,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100
+ },
+ "subqueries": [
+ {
+ "expression_cache": {
+ "r_loops": 50,
+ "r_hit_ratio": 0,
+ "query_block": {
+ "select_id": 2,
+ "r_loops": 50,
+ "r_total_time_ms": "REPLACED",
+ "filesort": {
+ "sort_key": "t2.a",
+ "r_loops": 50,
+ "r_total_time_ms": "REPLACED",
+ "r_used_priority_queue": false,
+ "r_output_rows": 1,
+ "r_buffer_size": "REPLACED" across executions)",
+ "r_sort_mode": "sort_key,rowid",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "r_loops": 50,
+ "rows": 50,
+ "r_rows": 50,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 2,
+ "attached_condition": "t1.b = t2.b"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+SELECT (SELECT sum(t2.b) FROM t2 WHERE t1.b=t2.b GROUP BY t2.a) FROM t1;
+(SELECT sum(t2.b) FROM t2 WHERE t1.b=t2.b GROUP BY t2.a)
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+set sort_buffer_size= @save_sort_buffer_size;
+DROP TABLE t1,t2;
# End of 10.5 tests
#
# MDEV-13694: Wrong result upon GROUP BY with orderby_uses_equalities=on
diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test
index fd87f54cc3d..05d9d45debe 100644
--- a/mysql-test/main/order_by.test
+++ b/mysql-test/main/order_by.test
@@ -2274,6 +2274,27 @@ ORDER BY id+1 DESC;
DROP TABLE t1;
+--echo #
+--echo # MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare
+--echo #
+
+SET @save_max_length_for_sort_data=@@max_length_for_sort_data;
+SET @save_max_sort_length= @@max_sort_length;
+SET @save_sql_select_limit= @@sql_select_limit;
+
+CREATE TABLE t1 (a DECIMAL(64,0), b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+
+SET max_length_for_sort_data= 30;
+SET sql_select_limit = 3;
+SET max_sort_length=8;
+SELECT * FROM t1 ORDER BY a+1;
+
+SET max_length_for_sort_data=@save_max_length_for_sort_data;
+SET max_sort_length= @save_max_sort_length;
+SET sql_select_limit= @save_sql_select_limit;
+DROP TABLE t1;
+
--echo # End of 10.2 tests
--echo #
@@ -2556,6 +2577,26 @@ INSERT t1 VALUES ('foo','bar'),('baz','qux');
SELECT COALESCE(a, b) AS f FROM t1 ORDER BY f;
DROP TABLE t1;
+--echo #
+--echo # MDEV-24015: SQL Error (1038): Out of sort memory when enough memory for the
+--echo # sort buffer is provided
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(100), b INT);
+CREATE TABLE t2 (a VARCHAR(100), b INT);
+
+INSERT INTO t1 SELECT 'abc', seq FROM seq_1_to_50;
+INSERT INTO t2 SELECT seq, seq FROM seq_1_to_50;
+
+set @save_sort_buffer_size= @@sort_buffer_size;
+set sort_buffer_size=2000;
+--source include/analyze-format.inc
+ANALYZE FORMAT=JSON
+SELECT (SELECT sum(t2.b) FROM t2 WHERE t1.b=t2.b GROUP BY t2.a) FROM t1;
+SELECT (SELECT sum(t2.b) FROM t2 WHERE t1.b=t2.b GROUP BY t2.a) FROM t1;
+
+set sort_buffer_size= @save_sort_buffer_size;
+DROP TABLE t1,t2;
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result
index 1d3acaf062b..86df20da9d8 100644
--- a/mysql-test/main/parser.result
+++ b/mysql-test/main/parser.result
@@ -1318,6 +1318,23 @@ t1 CREATE TABLE `t1` (
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+create or replace view v1 as select 1 between (2 between 3 and 4) and 5;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 between 2 between 3 and 4 and 5 AS `1 between (2 between 3 and 4) and 5`
+create or replace view v1 as select 1 between (2 in (3,4)) and 5;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 between 2 in (3,4) and 5 AS `1 between (2 in (3,4)) and 5`
+create or replace view v1 as select 1 between (2 like 3) and 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 between 2 like 3 and 4 AS `1 between (2 like 3) and 4`
+create or replace view v1 as select 1 not between (2 like 3) and 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 not between 2 like 3 and 4 AS `1 not between (2 like 3) and 4`
+drop view v1;
#
# MDEV-10343 Providing compatibility for basic SQL data types
#
@@ -1808,7 +1825,7 @@ EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST';
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 '`systeminfo /FO LIST' at line 1
EXECUTE IMMEDIATE 'if(`systeminfo';
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 '`systeminfo' at line 1
-End of 10.3 tests
+# End of 10.3 tests
#
# MDEV-19540: 10.4 allow lock options with SELECT in brackets
# which previous version do not
diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test
index 755cbb95c45..49f43600795 100644
--- a/mysql-test/main/parser.test
+++ b/mysql-test/main/parser.test
@@ -1346,6 +1346,20 @@ create table t1 ( id serial );
show create table t1;
drop table t1;
+#
+# BETWEEN syntax
+#
+create or replace view v1 as select 1 between (2 between 3 and 4) and 5;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+create or replace view v1 as select 1 between (2 in (3,4)) and 5;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+create or replace view v1 as select 1 between (2 like 3) and 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+create or replace view v1 as select 1 not between (2 like 3) and 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+drop view v1;
+
--echo #
--echo # MDEV-10343 Providing compatibility for basic SQL data types
--echo #
@@ -1552,7 +1566,7 @@ EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST';
--error ER_PARSE_ERROR
EXECUTE IMMEDIATE 'if(`systeminfo';
---echo End of 10.3 tests
+--echo # End of 10.3 tests
--echo #
--echo # MDEV-19540: 10.4 allow lock options with SELECT in brackets
diff --git a/mysql-test/main/parser_precedence.result b/mysql-test/main/parser_precedence.result
deleted file mode 100644
index f23295bd61b..00000000000
--- a/mysql-test/main/parser_precedence.result
+++ /dev/null
@@ -1,748 +0,0 @@
-drop table if exists t1_30237_bool;
-set sql_mode=NO_UNSIGNED_SUBTRACTION;
-create table t1_30237_bool(A boolean, B boolean, C boolean);
-insert into t1_30237_bool values
-(FALSE, FALSE, FALSE),
-(FALSE, FALSE, NULL),
-(FALSE, FALSE, TRUE),
-(FALSE, NULL, FALSE),
-(FALSE, NULL, NULL),
-(FALSE, NULL, TRUE),
-(FALSE, TRUE, FALSE),
-(FALSE, TRUE, NULL),
-(FALSE, TRUE, TRUE),
-(NULL, FALSE, FALSE),
-(NULL, FALSE, NULL),
-(NULL, FALSE, TRUE),
-(NULL, NULL, FALSE),
-(NULL, NULL, NULL),
-(NULL, NULL, TRUE),
-(NULL, TRUE, FALSE),
-(NULL, TRUE, NULL),
-(NULL, TRUE, TRUE),
-(TRUE, FALSE, FALSE),
-(TRUE, FALSE, NULL),
-(TRUE, FALSE, TRUE),
-(TRUE, NULL, FALSE),
-(TRUE, NULL, NULL),
-(TRUE, NULL, TRUE),
-(TRUE, TRUE, FALSE),
-(TRUE, TRUE, NULL),
-(TRUE, TRUE, TRUE) ;
-Testing OR, XOR, AND
-select A, B, A OR B, A XOR B, A AND B
-from t1_30237_bool where C is null order by A, B;
-A B A OR B A XOR B A AND B
-NULL NULL NULL NULL NULL
-NULL 0 NULL NULL 0
-NULL 1 1 NULL NULL
-0 NULL NULL NULL 0
-0 0 0 0 0
-0 1 1 1 0
-1 NULL 1 NULL NULL
-1 0 1 1 0
-1 1 1 0 1
-Testing that OR is associative
-select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
-from t1_30237_bool order by A, B, C;
-A B C (A OR B) OR C A OR (B OR C) A OR B OR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 1 1 1
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 NULL NULL NULL
-NULL 0 1 1 1 1
-NULL 1 NULL 1 1 1
-NULL 1 0 1 1 1
-NULL 1 1 1 1 1
-0 NULL NULL NULL NULL NULL
-0 NULL 0 NULL NULL NULL
-0 NULL 1 1 1 1
-0 0 NULL NULL NULL NULL
-0 0 0 0 0 0
-0 0 1 1 1 1
-0 1 NULL 1 1 1
-0 1 0 1 1 1
-0 1 1 1 1 1
-1 NULL NULL 1 1 1
-1 NULL 0 1 1 1
-1 NULL 1 1 1 1
-1 0 NULL 1 1 1
-1 0 0 1 1 1
-1 0 1 1 1 1
-1 1 NULL 1 1 1
-1 1 0 1 1 1
-1 1 1 1 1 1
-select count(*) from t1_30237_bool
-where ((A OR B) OR C) != (A OR (B OR C));
-count(*)
-0
-Testing that XOR is associative
-select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
-from t1_30237_bool order by A, B, C;
-A B C (A XOR B) XOR C A XOR (B XOR C) A XOR B XOR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 NULL NULL NULL
-NULL 0 1 NULL NULL NULL
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 NULL NULL NULL
-NULL 1 1 NULL NULL NULL
-0 NULL NULL NULL NULL NULL
-0 NULL 0 NULL NULL NULL
-0 NULL 1 NULL NULL NULL
-0 0 NULL NULL NULL NULL
-0 0 0 0 0 0
-0 0 1 1 1 1
-0 1 NULL NULL NULL NULL
-0 1 0 1 1 1
-0 1 1 0 0 0
-1 NULL NULL NULL NULL NULL
-1 NULL 0 NULL NULL NULL
-1 NULL 1 NULL NULL NULL
-1 0 NULL NULL NULL NULL
-1 0 0 1 1 1
-1 0 1 0 0 0
-1 1 NULL NULL NULL NULL
-1 1 0 0 0 0
-1 1 1 1 1 1
-select count(*) from t1_30237_bool
-where ((A XOR B) XOR C) != (A XOR (B XOR C));
-count(*)
-0
-Testing that AND is associative
-select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
-from t1_30237_bool order by A, B, C;
-A B C (A AND B) AND C A AND (B AND C) A AND B AND C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 0 0 0
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL 0 0 0
-NULL 0 0 0 0 0
-NULL 0 1 0 0 0
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 0 0 0
-NULL 1 1 NULL NULL NULL
-0 NULL NULL 0 0 0
-0 NULL 0 0 0 0
-0 NULL 1 0 0 0
-0 0 NULL 0 0 0
-0 0 0 0 0 0
-0 0 1 0 0 0
-0 1 NULL 0 0 0
-0 1 0 0 0 0
-0 1 1 0 0 0
-1 NULL NULL NULL NULL NULL
-1 NULL 0 0 0 0
-1 NULL 1 NULL NULL NULL
-1 0 NULL 0 0 0
-1 0 0 0 0 0
-1 0 1 0 0 0
-1 1 NULL NULL NULL NULL
-1 1 0 0 0 0
-1 1 1 1 1 1
-select count(*) from t1_30237_bool
-where ((A AND B) AND C) != (A AND (B AND C));
-count(*)
-0
-Testing that AND has precedence over OR
-select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
-from t1_30237_bool order by A, B, C;
-A B C (A OR B) AND C A OR (B AND C) A OR B AND C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 0 NULL NULL
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 0 NULL NULL
-NULL 0 1 NULL NULL NULL
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 0 NULL NULL
-NULL 1 1 1 1 1
-0 NULL NULL NULL NULL NULL
-0 NULL 0 0 0 0
-0 NULL 1 NULL NULL NULL
-0 0 NULL 0 0 0
-0 0 0 0 0 0
-0 0 1 0 0 0
-0 1 NULL NULL NULL NULL
-0 1 0 0 0 0
-0 1 1 1 1 1
-1 NULL NULL NULL 1 1
-1 NULL 0 0 1 1
-1 NULL 1 1 1 1
-1 0 NULL NULL 1 1
-1 0 0 0 1 1
-1 0 1 1 1 1
-1 1 NULL NULL 1 1
-1 1 0 0 1 1
-1 1 1 1 1 1
-select count(*) from t1_30237_bool
-where (A OR (B AND C)) != (A OR B AND C);
-count(*)
-0
-select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
-from t1_30237_bool order by A, B, C;
-A B C (A AND B) OR C A AND (B OR C) A AND B OR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 1 NULL 1
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 0 0 0
-NULL 0 1 1 NULL 1
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 NULL NULL NULL
-NULL 1 1 1 NULL 1
-0 NULL NULL NULL 0 NULL
-0 NULL 0 0 0 0
-0 NULL 1 1 0 1
-0 0 NULL NULL 0 NULL
-0 0 0 0 0 0
-0 0 1 1 0 1
-0 1 NULL NULL 0 NULL
-0 1 0 0 0 0
-0 1 1 1 0 1
-1 NULL NULL NULL NULL NULL
-1 NULL 0 NULL NULL NULL
-1 NULL 1 1 1 1
-1 0 NULL NULL NULL NULL
-1 0 0 0 0 0
-1 0 1 1 1 1
-1 1 NULL 1 1 1
-1 1 0 1 1 1
-1 1 1 1 1 1
-select count(*) from t1_30237_bool
-where ((A AND B) OR C) != (A AND B OR C);
-count(*)
-0
-Testing that AND has precedence over XOR
-select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
-from t1_30237_bool order by A, B, C;
-A B C (A XOR B) AND C A XOR (B AND C) A XOR B AND C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 0 NULL NULL
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 0 NULL NULL
-NULL 0 1 NULL NULL NULL
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 0 NULL NULL
-NULL 1 1 NULL NULL NULL
-0 NULL NULL NULL NULL NULL
-0 NULL 0 0 0 0
-0 NULL 1 NULL NULL NULL
-0 0 NULL 0 0 0
-0 0 0 0 0 0
-0 0 1 0 0 0
-0 1 NULL NULL NULL NULL
-0 1 0 0 0 0
-0 1 1 1 1 1
-1 NULL NULL NULL NULL NULL
-1 NULL 0 0 1 1
-1 NULL 1 NULL NULL NULL
-1 0 NULL NULL 1 1
-1 0 0 0 1 1
-1 0 1 1 1 1
-1 1 NULL 0 NULL NULL
-1 1 0 0 1 1
-1 1 1 0 0 0
-select count(*) from t1_30237_bool
-where (A XOR (B AND C)) != (A XOR B AND C);
-count(*)
-0
-select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
-from t1_30237_bool order by A, B, C;
-A B C (A AND B) XOR C A AND (B XOR C) A AND B XOR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 0 0 0
-NULL 0 1 1 NULL 1
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 NULL NULL NULL
-NULL 1 1 NULL 0 NULL
-0 NULL NULL NULL 0 NULL
-0 NULL 0 0 0 0
-0 NULL 1 1 0 1
-0 0 NULL NULL 0 NULL
-0 0 0 0 0 0
-0 0 1 1 0 1
-0 1 NULL NULL 0 NULL
-0 1 0 0 0 0
-0 1 1 1 0 1
-1 NULL NULL NULL NULL NULL
-1 NULL 0 NULL NULL NULL
-1 NULL 1 NULL NULL NULL
-1 0 NULL NULL NULL NULL
-1 0 0 0 0 0
-1 0 1 1 1 1
-1 1 NULL NULL NULL NULL
-1 1 0 1 1 1
-1 1 1 0 0 0
-select count(*) from t1_30237_bool
-where ((A AND B) XOR C) != (A AND B XOR C);
-count(*)
-0
-Testing that XOR has precedence over OR
-select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
-from t1_30237_bool order by A, B, C;
-A B C (A XOR B) OR C A XOR (B OR C) A XOR B OR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 1 NULL 1
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 NULL NULL NULL
-NULL 0 1 1 NULL 1
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 NULL NULL NULL
-NULL 1 1 1 NULL 1
-0 NULL NULL NULL NULL NULL
-0 NULL 0 NULL NULL NULL
-0 NULL 1 1 1 1
-0 0 NULL NULL NULL NULL
-0 0 0 0 0 0
-0 0 1 1 1 1
-0 1 NULL 1 1 1
-0 1 0 1 1 1
-0 1 1 1 1 1
-1 NULL NULL NULL NULL NULL
-1 NULL 0 NULL NULL NULL
-1 NULL 1 1 0 1
-1 0 NULL 1 NULL 1
-1 0 0 1 1 1
-1 0 1 1 0 1
-1 1 NULL NULL 0 NULL
-1 1 0 0 0 0
-1 1 1 1 0 1
-select count(*) from t1_30237_bool
-where ((A XOR B) OR C) != (A XOR B OR C);
-count(*)
-0
-select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
-from t1_30237_bool order by A, B, C;
-A B C (A OR B) XOR C A OR (B XOR C) A OR B XOR C
-NULL NULL NULL NULL NULL NULL
-NULL NULL 0 NULL NULL NULL
-NULL NULL 1 NULL NULL NULL
-NULL 0 NULL NULL NULL NULL
-NULL 0 0 NULL NULL NULL
-NULL 0 1 NULL 1 1
-NULL 1 NULL NULL NULL NULL
-NULL 1 0 1 1 1
-NULL 1 1 0 NULL NULL
-0 NULL NULL NULL NULL NULL
-0 NULL 0 NULL NULL NULL
-0 NULL 1 NULL NULL NULL
-0 0 NULL NULL NULL NULL
-0 0 0 0 0 0
-0 0 1 1 1 1
-0 1 NULL NULL NULL NULL
-0 1 0 1 1 1
-0 1 1 0 0 0
-1 NULL NULL NULL 1 1
-1 NULL 0 1 1 1
-1 NULL 1 0 1 1
-1 0 NULL NULL 1 1
-1 0 0 1 1 1
-1 0 1 0 1 1
-1 1 NULL NULL 1 1
-1 1 0 1 1 1
-1 1 1 0 1 1
-select count(*) from t1_30237_bool
-where (A OR (B XOR C)) != (A OR B XOR C);
-count(*)
-0
-drop table t1_30237_bool;
-Testing that NOT has precedence over OR
-select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE;
-(NOT FALSE) OR TRUE NOT (FALSE OR TRUE) NOT FALSE OR TRUE
-1 0 1
-Testing that NOT has precedence over XOR
-select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE;
-(NOT FALSE) XOR FALSE NOT (FALSE XOR FALSE) NOT FALSE XOR FALSE
-1 1 1
-Testing that NOT has precedence over AND
-select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE;
-(NOT FALSE) AND FALSE NOT (FALSE AND FALSE) NOT FALSE AND FALSE
-0 1 0
-Testing that NOT is associative
-select NOT NOT TRUE, NOT NOT NOT FALSE;
-NOT NOT TRUE NOT NOT NOT FALSE
-1 1
-Testing that IS has precedence over NOT
-select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE;
-(NOT NULL) IS TRUE NOT (NULL IS TRUE) NOT NULL IS TRUE
-0 1 1
-select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE;
-(NOT NULL) IS NOT TRUE NOT (NULL IS NOT TRUE) NOT NULL IS NOT TRUE
-1 0 0
-select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE;
-(NOT NULL) IS FALSE NOT (NULL IS FALSE) NOT NULL IS FALSE
-0 1 1
-select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE;
-(NOT NULL) IS NOT FALSE NOT (NULL IS NOT FALSE) NOT NULL IS NOT FALSE
-1 0 0
-select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN;
-(NOT TRUE) IS UNKNOWN NOT (TRUE IS UNKNOWN) NOT TRUE IS UNKNOWN
-0 1 1
-select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN;
-(NOT TRUE) IS NOT UNKNOWN NOT (TRUE IS NOT UNKNOWN) NOT TRUE IS NOT UNKNOWN
-1 0 0
-select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL;
-(NOT TRUE) IS NULL NOT (TRUE IS NULL) NOT TRUE IS NULL
-0 1 1
-select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL;
-(NOT TRUE) IS NOT NULL NOT (TRUE IS NOT NULL) NOT TRUE IS NOT NULL
-1 0 0
-Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative
-select TRUE IS TRUE IS TRUE IS TRUE;
-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 'IS TRUE IS TRUE' at line 1
-select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE;
-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 'IS NOT TRUE IS NOT TRUE' at line 1
-select NULL IS FALSE IS FALSE IS FALSE;
-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 'IS FALSE IS FALSE' at line 1
-select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE;
-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 'IS NOT FALSE IS NOT FALSE' at line 1
-select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN;
-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 'IS UNKNOWN IS UNKNOWN' at line 1
-select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN;
-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 'IS NOT UNKNOWN IS NOT UNKNOWN' at line 1
-Testing that IS [NOT] NULL predicates are associative
-select FALSE IS NULL IS NULL IS NULL;
-FALSE IS NULL IS NULL IS NULL
-0
-select TRUE IS NOT NULL IS NOT NULL IS NOT NULL;
-TRUE IS NOT NULL IS NOT NULL IS NOT NULL
-1
-Testing that comparison operators are left associative
-select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2);
-1 <=> 2 <=> 2 (1 <=> 2) <=> 2 1 <=> (2 <=> 2)
-0 0 1
-select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2);
-1 = 2 = 2 (1 = 2) = 2 1 = (2 = 2)
-0 0 1
-select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3);
-1 != 2 != 3 (1 != 2) != 3 1 != (2 != 3)
-1 1 0
-select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3);
-1 <> 2 <> 3 (1 <> 2) <> 3 1 <> (2 <> 3)
-1 1 0
-select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3);
-1 < 2 < 3 (1 < 2) < 3 1 < (2 < 3)
-1 1 0
-select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1);
-3 <= 2 <= 1 (3 <= 2) <= 1 3 <= (2 <= 1)
-1 1 0
-select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3);
-1 > 2 > 3 (1 > 2) > 3 1 > (2 > 3)
-0 0 1
-select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3);
-1 >= 2 >= 3 (1 >= 2) >= 3 1 >= (2 >= 3)
-0 0 1
-Testing that | is associative
-select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55);
-0xF0 | 0x0F | 0x55 (0xF0 | 0x0F) | 0x55 0xF0 | (0x0F | 0x55)
-255 255 255
-Testing that & is associative
-select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55);
-0xF5 & 0x5F & 0x55 (0xF5 & 0x5F) & 0x55 0xF5 & (0x5F & 0x55)
-85 85 85
-Testing that << is left associative
-select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2);
-4 << 3 << 2 (4 << 3) << 2 4 << (3 << 2)
-128 128 16384
-Testing that >> is left associative
-select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2);
-256 >> 3 >> 2 (256 >> 3) >> 2 256 >> (3 >> 2)
-8 8 256
-Testing that & has precedence over |
-select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55);
-0xF0 & 0x0F | 0x55 (0xF0 & 0x0F) | 0x55 0xF0 & (0x0F | 0x55)
-85 85 80
-select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F);
-0x55 | 0xF0 & 0x0F (0x55 | 0xF0) & 0x0F 0x55 | (0xF0 & 0x0F)
-85 5 85
-Testing that << has precedence over |
-select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F);
-0x0F << 4 | 0x0F (0x0F << 4) | 0x0F 0x0F << (4 | 0x0F)
-255 255 491520
-select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4);
-0x0F | 0x0F << 4 (0x0F | 0x0F) << 4 0x0F | (0x0F << 4)
-255 240 255
-Testing that >> has precedence over |
-select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF);
-0xF0 >> 4 | 0xFF (0xF0 >> 4) | 0xFF 0xF0 >> (4 | 0xFF)
-255 255 0
-select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4);
-0xFF | 0xF0 >> 4 (0xFF | 0xF0) >> 4 0xFF | (0xF0 >> 4)
-255 15 255
-Testing that << has precedence over &
-select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0);
-0x0F << 4 & 0xF0 (0x0F << 4) & 0xF0 0x0F << (4 & 0xF0)
-240 240 15
-select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4);
-0xF0 & 0x0F << 4 (0xF0 & 0x0F) << 4 0xF0 & (0x0F << 4)
-240 0 240
-Testing that >> has precedence over &
-select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55);
-0xF0 >> 4 & 0x55 (0xF0 >> 4) & 0x55 0xF0 >> (4 & 0x55)
-5 5 15
-select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4);
-0x0F & 0xF0 >> 4 (0x0F & 0xF0) >> 4 0x0F & (0xF0 >> 4)
-15 0 15
-Testing that >> and << have the same precedence
-select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2);
-0xFF >> 4 << 2 (0xFF >> 4) << 2 0xFF >> (4 << 2)
-60 60 0
-select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2);
-0x0F << 4 >> 2 (0x0F << 4) >> 2 0x0F << (4 >> 2)
-60 60 30
-Testing that binary + is associative
-select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3);
-1 + 2 + 3 (1 + 2) + 3 1 + (2 + 3)
-6 6 6
-Testing that binary - is left associative
-select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3);
-1 - 2 - 3 (1 - 2) - 3 1 - (2 - 3)
--4 -4 2
-Testing that binary + and binary - have the same precedence
-select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3);
-1 + 2 - 3 (1 + 2) - 3 1 + (2 - 3)
-0 0 0
-select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3);
-1 - 2 + 3 (1 - 2) + 3 1 - (2 + 3)
-2 2 -4
-Testing that binary + has precedence over |
-select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55);
-0xF0 + 0x0F | 0x55 (0xF0 + 0x0F) | 0x55 0xF0 + (0x0F | 0x55)
-255 255 335
-select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F);
-0x55 | 0xF0 + 0x0F (0x55 | 0xF0) + 0x0F 0x55 | (0xF0 + 0x0F)
-255 260 255
-Testing that binary + has precedence over &
-select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55);
-0xF0 + 0x0F & 0x55 (0xF0 + 0x0F) & 0x55 0xF0 + (0x0F & 0x55)
-85 85 245
-select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F);
-0x55 & 0xF0 + 0x0F (0x55 & 0xF0) + 0x0F 0x55 & (0xF0 + 0x0F)
-85 95 85
-Testing that binary + has precedence over <<
-select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4);
-2 + 3 << 4 (2 + 3) << 4 2 + (3 << 4)
-80 80 50
-select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2);
-3 << 4 + 2 (3 << 4) + 2 3 << (4 + 2)
-192 50 192
-Testing that binary + has precedence over >>
-select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2);
-4 + 3 >> 2 (4 + 3) >> 2 4 + (3 >> 2)
-1 1 4
-select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1);
-3 >> 2 + 1 (3 >> 2) + 1 3 >> (2 + 1)
-0 1 0
-Testing that binary - has precedence over |
-select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55);
-0xFF - 0x0F | 0x55 (0xFF - 0x0F) | 0x55 0xFF - (0x0F | 0x55)
-245 245 160
-select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0);
-0x55 | 0xFF - 0xF0 (0x55 | 0xFF) - 0xF0 0x55 | (0xFF - 0xF0)
-95 15 95
-Testing that binary - has precedence over &
-select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55);
-0xFF - 0xF0 & 0x55 (0xFF - 0xF0) & 0x55 0xFF - (0xF0 & 0x55)
-5 5 175
-select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0);
-0x55 & 0xFF - 0xF0 (0x55 & 0xFF) - 0xF0 0x55 & (0xFF - 0xF0)
-5 -155 5
-Testing that binary - has precedence over <<
-select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2);
-16 - 3 << 2 (16 - 3) << 2 16 - (3 << 2)
-52 52 4
-select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2);
-4 << 3 - 2 (4 << 3) - 2 4 << (3 - 2)
-8 30 8
-Testing that binary - has precedence over >>
-select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2);
-16 - 3 >> 2 (16 - 3) >> 2 16 - (3 >> 2)
-3 3 16
-select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2);
-16 >> 3 - 2 (16 >> 3) - 2 16 >> (3 - 2)
-8 0 8
-Testing that * is associative
-select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4);
-2 * 3 * 4 (2 * 3) * 4 2 * (3 * 4)
-24 24 24
-Testing that * has precedence over |
-select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F);
-2 * 0x40 | 0x0F (2 * 0x40) | 0x0F 2 * (0x40 | 0x0F)
-143 143 158
-select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40);
-0x0F | 2 * 0x40 (0x0F | 2) * 0x40 0x0F | (2 * 0x40)
-143 960 143
-Testing that * has precedence over &
-select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55);
-2 * 0x40 & 0x55 (2 * 0x40) & 0x55 2 * (0x40 & 0x55)
-0 0 128
-select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40);
-0xF0 & 2 * 0x40 (0xF0 & 2) * 0x40 0xF0 & (2 * 0x40)
-128 0 128
-Testing that * has precedence over <<
-select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4);
-5 * 3 << 4 (5 * 3) << 4 5 * (3 << 4)
-240 240 240
-select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4);
-2 << 3 * 4 (2 << 3) * 4 2 << (3 * 4)
-8192 64 8192
-Testing that * has precedence over >>
-select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2);
-3 * 4 >> 2 (3 * 4) >> 2 3 * (4 >> 2)
-3 3 3
-select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3);
-4 >> 2 * 3 (4 >> 2) * 3 4 >> (2 * 3)
-0 3 0
-Testing that * has precedence over binary +
-select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4);
-2 * 3 + 4 (2 * 3) + 4 2 * (3 + 4)
-10 10 14
-select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4);
-2 + 3 * 4 (2 + 3) * 4 2 + (3 * 4)
-14 20 14
-Testing that * has precedence over binary -
-select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2);
-4 * 3 - 2 (4 * 3) - 2 4 * (3 - 2)
-10 10 4
-select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2);
-4 - 3 * 2 (4 - 3) * 2 4 - (3 * 2)
--2 2 -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 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)
-23 23 15.0000
-select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5);
-105 | 2 / 5 (105 | 2) / 5 105 | (2 / 5)
-105 21.4000 105
-Testing that / has precedence over &
-select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F);
-105 / 5 & 0x0F (105 / 5) & 0x0F 105 / (5 & 0x0F)
-5 5 21.0000
-select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5);
-0x0F & 105 / 5 (0x0F & 105) / 5 0x0F & (105 / 5)
-5 1.8000 5
-Testing that / has precedence over <<
-select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2);
-0x80 / 4 << 2 (0x80 / 4) << 2 0x80 / (4 << 2)
-128 128 8.0000
-select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2);
-0x80 << 4 / 2 (0x80 << 4) / 2 0x80 << (4 / 2)
-512 1024.0000 512
-Testing that / has precedence over >>
-select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2);
-0x80 / 4 >> 2 (0x80 / 4) >> 2 0x80 / (4 >> 2)
-8 8 128.0000
-select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2);
-0x80 >> 4 / 2 (0x80 >> 4) / 2 0x80 >> (4 / 2)
-32 4.0000 32
-Testing that / has precedence over binary +
-select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2);
-0x80 / 2 + 2 (0x80 / 2) + 2 0x80 / (2 + 2)
-66.0000 66.0000 32.0000
-select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2);
-0x80 + 2 / 2 (0x80 + 2) / 2 0x80 + (2 / 2)
-129.0000 65.0000 129.0000
-Testing that / has precedence over binary -
-select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2);
-0x80 / 4 - 2 (0x80 / 4) - 2 0x80 / (4 - 2)
-30.0000 30.0000 64.0000
-select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2);
-0x80 - 4 / 2 (0x80 - 4) / 2 0x80 - (4 / 2)
-126.0000 62.0000 126.0000
-Testing that ^ is associative
-select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F);
-0xFF ^ 0xF0 ^ 0x0F (0xFF ^ 0xF0) ^ 0x0F 0xFF ^ (0xF0 ^ 0x0F)
-0 0 0
-select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55);
-0xFF ^ 0xF0 ^ 0x55 (0xFF ^ 0xF0) ^ 0x55 0xFF ^ (0xF0 ^ 0x55)
-90 90 90
-Testing that ^ has precedence over |
-select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F);
-0xFF ^ 0xF0 | 0x0F (0xFF ^ 0xF0) | 0x0F 0xFF ^ (0xF0 | 0x0F)
-15 15 0
-select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0);
-0xF0 | 0xFF ^ 0xF0 (0xF0 | 0xFF) ^ 0xF0 0xF0 | (0xFF ^ 0xF0)
-255 15 255
-Testing that ^ has precedence over &
-select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F);
-0xFF ^ 0xF0 & 0x0F (0xFF ^ 0xF0) & 0x0F 0xFF ^ (0xF0 & 0x0F)
-15 15 255
-select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0);
-0x0F & 0xFF ^ 0xF0 (0x0F & 0xFF) ^ 0xF0 0x0F & (0xFF ^ 0xF0)
-15 255 15
-Testing that ^ has precedence over <<
-select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2);
-0xFF ^ 0xF0 << 2 (0xFF ^ 0xF0) << 2 0xFF ^ (0xF0 << 2)
-60 60 831
-select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF);
-0x0F << 2 ^ 0xFF (0x0F << 2) ^ 0xFF 0x0F << (2 ^ 0xFF)
-0 195 0
-Testing that ^ has precedence over >>
-select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2);
-0xFF ^ 0xF0 >> 2 (0xFF ^ 0xF0) >> 2 0xFF ^ (0xF0 >> 2)
-3 3 195
-select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0);
-0xFF >> 2 ^ 0xF0 (0xFF >> 2) ^ 0xF0 0xFF >> (2 ^ 0xF0)
-0 207 0
-Testing that ^ has precedence over binary +
-select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F);
-0xFF ^ 0xF0 + 0x0F (0xFF ^ 0xF0) + 0x0F 0xFF ^ (0xF0 + 0x0F)
-30 30 0
-select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0);
-0x0F + 0xFF ^ 0xF0 (0x0F + 0xFF) ^ 0xF0 0x0F + (0xFF ^ 0xF0)
-30 510 30
-Testing that ^ has precedence over binary -
-select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1);
-0xFF ^ 0xF0 - 1 (0xFF ^ 0xF0) - 1 0xFF ^ (0xF0 - 1)
-14 14 16
-select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55);
-0x55 - 0x0F ^ 0x55 (0x55 - 0x0F) ^ 0x55 0x55 - (0x0F ^ 0x55)
--5 19 -5
-Testing that ^ has precedence over *
-select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2);
-0xFF ^ 0xF0 * 2 (0xFF ^ 0xF0) * 2 0xFF ^ (0xF0 * 2)
-30 30 287
-select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0);
-2 * 0xFF ^ 0xF0 (2 * 0xFF) ^ 0xF0 2 * (0xFF ^ 0xF0)
-30 270 30
-Testing that ^ has precedence over /
-select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2);
-0xFF ^ 0xF0 / 2 (0xFF ^ 0xF0) / 2 0xFF ^ (0xF0 / 2)
-7.5000 7.5000 135
-select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0);
-0xF2 / 2 ^ 0xF0 (0xF2 / 2) ^ 0xF0 0xF2 / (2 ^ 0xF0)
-1.0000 137 1.0000
-Testing that ^ has precedence over %
-select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20);
-0xFF ^ 0xF0 % 0x20 (0xFF ^ 0xF0) % 0x20 0xFF ^ (0xF0 % 0x20)
-15 15 239
-select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0);
-0xFF % 0x20 ^ 0xF0 (0xFF % 0x20) ^ 0xF0 0xFF % (0x20 ^ 0xF0)
-47 239 47
-Testing that ^ has precedence over DIV
-select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2);
-0xFF ^ 0xF0 DIV 2 (0xFF ^ 0xF0) DIV 2 0xFF ^ (0xF0 DIV 2)
-7 7 135
-select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0);
-0xF2 DIV 2 ^ 0xF0 (0xF2 DIV 2) ^ 0xF0 0xF2 DIV (2 ^ 0xF0)
-1 137 1
-Testing that ^ has precedence over MOD
-select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20);
-0xFF ^ 0xF0 MOD 0x20 (0xFF ^ 0xF0) MOD 0x20 0xFF ^ (0xF0 MOD 0x20)
-15 15 239
-select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0);
-0xFF MOD 0x20 ^ 0xF0 (0xFF MOD 0x20) ^ 0xF0 0xFF MOD (0x20 ^ 0xF0)
-47 239 47
diff --git a/mysql-test/main/parser_precedence.test b/mysql-test/main/parser_precedence.test
deleted file mode 100644
index 7b69bc9c6da..00000000000
--- a/mysql-test/main/parser_precedence.test
+++ /dev/null
@@ -1,335 +0,0 @@
-
---disable_warnings
-drop table if exists t1_30237_bool;
---enable_warnings
-
-set sql_mode=NO_UNSIGNED_SUBTRACTION;
-
-create table t1_30237_bool(A boolean, B boolean, C boolean);
-
-insert into t1_30237_bool values
-(FALSE, FALSE, FALSE),
-(FALSE, FALSE, NULL),
-(FALSE, FALSE, TRUE),
-(FALSE, NULL, FALSE),
-(FALSE, NULL, NULL),
-(FALSE, NULL, TRUE),
-(FALSE, TRUE, FALSE),
-(FALSE, TRUE, NULL),
-(FALSE, TRUE, TRUE),
-(NULL, FALSE, FALSE),
-(NULL, FALSE, NULL),
-(NULL, FALSE, TRUE),
-(NULL, NULL, FALSE),
-(NULL, NULL, NULL),
-(NULL, NULL, TRUE),
-(NULL, TRUE, FALSE),
-(NULL, TRUE, NULL),
-(NULL, TRUE, TRUE),
-(TRUE, FALSE, FALSE),
-(TRUE, FALSE, NULL),
-(TRUE, FALSE, TRUE),
-(TRUE, NULL, FALSE),
-(TRUE, NULL, NULL),
-(TRUE, NULL, TRUE),
-(TRUE, TRUE, FALSE),
-(TRUE, TRUE, NULL),
-(TRUE, TRUE, TRUE) ;
-
---echo Testing OR, XOR, AND
-select A, B, A OR B, A XOR B, A AND B
- from t1_30237_bool where C is null order by A, B;
-
---echo Testing that OR is associative
-select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
- from t1_30237_bool order by A, B, C;
-
-select count(*) from t1_30237_bool
- where ((A OR B) OR C) != (A OR (B OR C));
-
---echo Testing that XOR is associative
-select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
- from t1_30237_bool order by A, B, C;
-
-select count(*) from t1_30237_bool
- where ((A XOR B) XOR C) != (A XOR (B XOR C));
-
---echo Testing that AND is associative
-select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
- from t1_30237_bool order by A, B, C;
-
-select count(*) from t1_30237_bool
- where ((A AND B) AND C) != (A AND (B AND C));
-
---echo Testing that AND has precedence over OR
-select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where (A OR (B AND C)) != (A OR B AND C);
-select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where ((A AND B) OR C) != (A AND B OR C);
-
---echo Testing that AND has precedence over XOR
-select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where (A XOR (B AND C)) != (A XOR B AND C);
-select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where ((A AND B) XOR C) != (A AND B XOR C);
-
---echo Testing that XOR has precedence over OR
-select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where ((A XOR B) OR C) != (A XOR B OR C);
-select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
- from t1_30237_bool order by A, B, C;
-select count(*) from t1_30237_bool
- where (A OR (B XOR C)) != (A OR B XOR C);
-
-drop table t1_30237_bool;
-
---echo Testing that NOT has precedence over OR
-select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE;
-
---echo Testing that NOT has precedence over XOR
-select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE;
-
---echo Testing that NOT has precedence over AND
-select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE;
-
---echo Testing that NOT is associative
-select NOT NOT TRUE, NOT NOT NOT FALSE;
-
---echo Testing that IS has precedence over NOT
-select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE;
-select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE;
-select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE;
-select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE;
-select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN;
-select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN;
-select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL;
-select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL;
-
---echo Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative
-# Documenting existing behavior in 5.0.48
--- error ER_PARSE_ERROR
-select TRUE IS TRUE IS TRUE IS TRUE;
--- error ER_PARSE_ERROR
-select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE;
--- error ER_PARSE_ERROR
-select NULL IS FALSE IS FALSE IS FALSE;
--- error ER_PARSE_ERROR
-select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE;
--- error ER_PARSE_ERROR
-select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN;
--- error ER_PARSE_ERROR
-select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN;
-
---echo Testing that IS [NOT] NULL predicates are associative
-# Documenting existing behavior in 5.0.48
-select FALSE IS NULL IS NULL IS NULL;
-select TRUE IS NOT NULL IS NOT NULL IS NOT NULL;
-
---echo Testing that comparison operators are left associative
-select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2);
-select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2);
-select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3);
-select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3);
-select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3);
-select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1);
-select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3);
-select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3);
-
--- echo Testing that | is associative
-select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55);
-
--- echo Testing that & is associative
-select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55);
-
--- echo Testing that << is left associative
-select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2);
-
--- echo Testing that >> is left associative
-select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2);
-
---echo Testing that & has precedence over |
-select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55);
-select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F);
-
---echo Testing that << has precedence over |
-select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F);
-select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4);
-
---echo Testing that >> has precedence over |
-select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF);
-select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4);
-
---echo Testing that << has precedence over &
-select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0);
-select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4);
-
---echo Testing that >> has precedence over &
-select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55);
-select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4);
-
---echo Testing that >> and << have the same precedence
-select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2);
-select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2);
-
---echo Testing that binary + is associative
-select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3);
-
---echo Testing that binary - is left associative
-select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3);
-
---echo Testing that binary + and binary - have the same precedence
-# evaluated left to right
-select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3);
-select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3);
-
---echo Testing that binary + has precedence over |
-select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55);
-select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F);
-
---echo Testing that binary + has precedence over &
-select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55);
-select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F);
-
---echo Testing that binary + has precedence over <<
-select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4);
-select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2);
-
---echo Testing that binary + has precedence over >>
-select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2);
-select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1);
-
---echo Testing that binary - has precedence over |
-select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55);
-select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0);
-
---echo Testing that binary - has precedence over &
-select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55);
-select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0);
-
---echo Testing that binary - has precedence over <<
-select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2);
-select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2);
-
---echo Testing that binary - has precedence over >>
-select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2);
-select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2);
-
---echo Testing that * is associative
-select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4);
-
---echo Testing that * has precedence over |
-select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F);
-select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40);
-
---echo Testing that * has precedence over &
-select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55);
-select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40);
-
---echo Testing that * has precedence over <<
-# Actually, can't prove it for the first case,
-# since << is a multiplication by a power of 2,
-# and * is associative
-select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4);
-select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4);
-
---echo Testing that * has precedence over >>
-# >> is a multiplication by a (negative) power of 2,
-# see above.
-select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2);
-select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3);
-
---echo Testing that * has precedence over binary +
-select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4);
-select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4);
-
---echo Testing that * has precedence over binary -
-select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2);
-select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2);
-
---echo Testing that / is left associative
-select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3);
-
---echo Testing that / has precedence over |
-select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2);
-select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5);
-
---echo Testing that / has precedence over &
-select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F);
-select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5);
-
---echo Testing that / has precedence over <<
-select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2);
-select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2);
-
---echo Testing that / has precedence over >>
-select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2);
-select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2);
-
---echo Testing that / has precedence over binary +
-select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2);
-select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2);
-
---echo Testing that / has precedence over binary -
-select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2);
-select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2);
-
-# TODO: %, DIV, MOD
-
---echo Testing that ^ is associative
-select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F);
-select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55);
-
---echo Testing that ^ has precedence over |
-select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F);
-select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0);
-
---echo Testing that ^ has precedence over &
-select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F);
-select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0);
-
---echo Testing that ^ has precedence over <<
-select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2);
-select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF);
-
---echo Testing that ^ has precedence over >>
-select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2);
-select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0);
-
---echo Testing that ^ has precedence over binary +
-select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F);
-select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0);
-
---echo Testing that ^ has precedence over binary -
-select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1);
-select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55);
-
---echo Testing that ^ has precedence over *
-select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2);
-select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0);
-
---echo Testing that ^ has precedence over /
-select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2);
-select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0);
-
---echo Testing that ^ has precedence over %
-select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20);
-select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0);
-
---echo Testing that ^ has precedence over DIV
-select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2);
-select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0);
-
---echo Testing that ^ has precedence over MOD
-select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20);
-select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0);
-
diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result
index 6f97cd013b3..373522ded40 100644
--- a/mysql-test/main/partition.result
+++ b/mysql-test/main/partition.result
@@ -2807,5 +2807,16 @@ id
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/main/partition.test b/mysql-test/main/partition.test
index b715866fab8..81752982959 100644
--- a/mysql-test/main/partition.test
+++ b/mysql-test/main/partition.test
@@ -3005,5 +3005,21 @@ 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/main/plugin_innodb.test b/mysql-test/main/plugin_innodb.test
index c0733570de1..d458299a900 100644
--- a/mysql-test/main/plugin_innodb.test
+++ b/mysql-test/main/plugin_innodb.test
@@ -1,13 +1,6 @@
--source include/not_embedded.inc
--source include/have_example_plugin.inc
---source include/have_innodb.inc
-
-if (!`select count(*) from information_schema.plugins
- where plugin_name = 'innodb' and plugin_status = 'active' and
- plugin_library is null`) {
- skip Need compiled-in InnoDB;
-}
-
+--source include/have_static_innodb.inc
install plugin example soname 'ha_example';
create table t1(a int) engine=example;
diff --git a/mysql-test/main/pool_of_threads.result b/mysql-test/main/pool_of_threads.result
index fd3c848117c..d4a7d9092f4 100644
--- a/mysql-test/main/pool_of_threads.result
+++ b/mysql-test/main/pool_of_threads.result
@@ -2180,11 +2180,14 @@ connection extracon2;
KILL QUERY <default_connection_ID>;
KILL QUERY <con2_connection_ID>;
connection default;
-sleep(50)
-1
+ERROR 70100: Query execution was interrupted
connection con2;
-sleep(50)
-1
+ERROR 70100: Query execution was interrupted
connection extracon;
sleep(5.5)
0
+connect comp_con,localhost,root,,,,,COMPRESS;
+SELECT 1;
+1
+1
+disconnect comp_con;
diff --git a/mysql-test/main/pool_of_threads.test b/mysql-test/main/pool_of_threads.test
index cb62a27faeb..3d581d4605d 100644
--- a/mysql-test/main/pool_of_threads.test
+++ b/mysql-test/main/pool_of_threads.test
@@ -86,9 +86,17 @@ eval KILL QUERY $con1_id;
eval KILL QUERY $con2_id;
connection default;
+--error ER_QUERY_INTERRUPTED
--reap
connection con2;
+--error ER_QUERY_INTERRUPTED
--reap
connection extracon;
--reap
+
+# Check if compression works OK
+connect (comp_con,localhost,root,,,,,COMPRESS);
+SELECT 1;
+disconnect comp_con;
+
diff --git a/mysql-test/main/precedence.result b/mysql-test/main/precedence.result
new file mode 100644
index 00000000000..d5d4e662a8e
--- /dev/null
+++ b/mysql-test/main/precedence.result
@@ -0,0 +1,8019 @@
+create or replace view v1 as select NOT NULL IS TRUE, NOT (NULL IS TRUE), (NOT NULL) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(NULL is true) AS `NOT NULL IS TRUE`,!(NULL is true) AS `NOT (NULL IS TRUE)`,!NULL is true AS `(NOT NULL) IS TRUE`
+select NOT NULL IS TRUE, NOT (NULL IS TRUE), (NOT NULL) IS TRUE union select * from v1;
+NOT NULL IS TRUE NOT (NULL IS TRUE) (NOT NULL) IS TRUE
+1 1 0
+create or replace view v1 as select ! NULL IS TRUE, ! (NULL IS TRUE), (! NULL) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !NULL is true AS `! NULL IS TRUE`,!(NULL is true) AS `! (NULL IS TRUE)`,!NULL is true AS `(! NULL) IS TRUE`
+select ! NULL IS TRUE, ! (NULL IS TRUE), (! NULL) IS TRUE union select * from v1;
+! NULL IS TRUE ! (NULL IS TRUE) (! NULL) IS TRUE
+0 1 0
+create or replace view v1 as select charset(NOT 2 COLLATE latin1_bin), charset(NOT (2 COLLATE latin1_bin)), charset((NOT 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(!2 collate latin1_bin) AS `charset(NOT 2 COLLATE latin1_bin)`,charset(!2 collate latin1_bin) AS `charset(NOT (2 COLLATE latin1_bin))`,charset((!2) collate latin1_bin) AS `charset((NOT 2) COLLATE latin1_bin)`
+select charset(NOT 2 COLLATE latin1_bin), charset(NOT (2 COLLATE latin1_bin)), charset((NOT 2) COLLATE latin1_bin) union select * from v1;
+charset(NOT 2 COLLATE latin1_bin) charset(NOT (2 COLLATE latin1_bin)) charset((NOT 2) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select NOT 2 IN (0,2), NOT (2 IN (0,2)), (NOT 2) IN (0,2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 not in (0,2) AS `NOT 2 IN (0,2)`,2 not in (0,2) AS `NOT (2 IN (0,2))`,!2 in (0,2) AS `(NOT 2) IN (0,2)`
+select NOT 2 IN (0,2), NOT (2 IN (0,2)), (NOT 2) IN (0,2) union select * from v1;
+NOT 2 IN (0,2) NOT (2 IN (0,2)) (NOT 2) IN (0,2)
+0 0 1
+create or replace view v1 as select NOT 2 OR 3, NOT (2 OR 3), (NOT 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 or 3 AS `NOT 2 OR 3`,!2 and !3 AS `NOT (2 OR 3)`,!2 or 3 AS `(NOT 2) OR 3`
+select NOT 2 OR 3, NOT (2 OR 3), (NOT 2) OR 3 union select * from v1;
+NOT 2 OR 3 NOT (2 OR 3) (NOT 2) OR 3
+1 0 1
+create or replace view v1 as select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 or 3 AS `NOT 2 || 3`,!2 and !3 AS `NOT (2 || 3)`,!2 or 3 AS `(NOT 2) || 3`
+select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3 union select * from v1;
+NOT 2 || 3 NOT (2 || 3) (NOT 2) || 3
+1 0 1
+create or replace view v1 as select NOT 2 AND 0, NOT (2 AND 0), (NOT 2) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 and 0 AS `NOT 2 AND 0`,!2 or !0 AS `NOT (2 AND 0)`,!2 and 0 AS `(NOT 2) AND 0`
+select NOT 2 AND 0, NOT (2 AND 0), (NOT 2) AND 0 union select * from v1;
+NOT 2 AND 0 NOT (2 AND 0) (NOT 2) AND 0
+0 1 0
+create or replace view v1 as select NOT 2 && 0, NOT (2 && 0), (NOT 2) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 and 0 AS `NOT 2 && 0`,!2 or !0 AS `NOT (2 && 0)`,!2 and 0 AS `(NOT 2) && 0`
+select NOT 2 && 0, NOT (2 && 0), (NOT 2) && 0 union select * from v1;
+NOT 2 && 0 NOT (2 && 0) (NOT 2) && 0
+0 1 0
+create or replace view v1 as select NOT 2 = 3, NOT (2 = 3), (NOT 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 AS `NOT 2 = 3`,2 <> 3 AS `NOT (2 = 3)`,!2 = 3 AS `(NOT 2) = 3`
+select NOT 2 = 3, NOT (2 = 3), (NOT 2) = 3 union select * from v1;
+NOT 2 = 3 NOT (2 = 3) (NOT 2) = 3
+1 1 0
+create or replace view v1 as select NOT 2 <=> 3, NOT (2 <=> 3), (NOT 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 <=> 3) AS `NOT 2 <=> 3`,!(2 <=> 3) AS `NOT (2 <=> 3)`,!2 <=> 3 AS `(NOT 2) <=> 3`
+select NOT 2 <=> 3, NOT (2 <=> 3), (NOT 2) <=> 3 union select * from v1;
+NOT 2 <=> 3 NOT (2 <=> 3) (NOT 2) <=> 3
+1 1 0
+create or replace view v1 as select NOT 2 >= 3, NOT (2 >= 3), (NOT 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 AS `NOT 2 >= 3`,2 < 3 AS `NOT (2 >= 3)`,!2 >= 3 AS `(NOT 2) >= 3`
+select NOT 2 >= 3, NOT (2 >= 3), (NOT 2) >= 3 union select * from v1;
+NOT 2 >= 3 NOT (2 >= 3) (NOT 2) >= 3
+1 1 0
+create or replace view v1 as select NOT 2 <= 3, NOT (2 <= 3), (NOT 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 AS `NOT 2 <= 3`,2 > 3 AS `NOT (2 <= 3)`,!2 <= 3 AS `(NOT 2) <= 3`
+select NOT 2 <= 3, NOT (2 <= 3), (NOT 2) <= 3 union select * from v1;
+NOT 2 <= 3 NOT (2 <= 3) (NOT 2) <= 3
+0 0 1
+create or replace view v1 as select NOT 2 < 3, NOT (2 < 3), (NOT 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 AS `NOT 2 < 3`,2 >= 3 AS `NOT (2 < 3)`,!2 < 3 AS `(NOT 2) < 3`
+select NOT 2 < 3, NOT (2 < 3), (NOT 2) < 3 union select * from v1;
+NOT 2 < 3 NOT (2 < 3) (NOT 2) < 3
+0 0 1
+create or replace view v1 as select NOT 2 <> 3, NOT (2 <> 3), (NOT 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 AS `NOT 2 <> 3`,2 = 3 AS `NOT (2 <> 3)`,!2 <> 3 AS `(NOT 2) <> 3`
+select NOT 2 <> 3, NOT (2 <> 3), (NOT 2) <> 3 union select * from v1;
+NOT 2 <> 3 NOT (2 <> 3) (NOT 2) <> 3
+0 0 1
+create or replace view v1 as select NOT 2 > 3, NOT (2 > 3), (NOT 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 AS `NOT 2 > 3`,2 <= 3 AS `NOT (2 > 3)`,!2 > 3 AS `(NOT 2) > 3`
+select NOT 2 > 3, NOT (2 > 3), (NOT 2) > 3 union select * from v1;
+NOT 2 > 3 NOT (2 > 3) (NOT 2) > 3
+1 1 0
+create or replace view v1 as select NOT 2 != 3, NOT (2 != 3), (NOT 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 AS `NOT 2 != 3`,2 = 3 AS `NOT (2 != 3)`,!2 <> 3 AS `(NOT 2) != 3`
+select NOT 2 != 3, NOT (2 != 3), (NOT 2) != 3 union select * from v1;
+NOT 2 != 3 NOT (2 != 3) (NOT 2) != 3
+0 0 1
+create or replace view v1 as select NOT 2 LIKE 3, NOT (2 LIKE 3), (NOT 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 not like 3 AS `NOT 2 LIKE 3`,2 not like 3 AS `NOT (2 LIKE 3)`,!2 like 3 AS `(NOT 2) LIKE 3`
+select NOT 2 LIKE 3, NOT (2 LIKE 3), (NOT 2) LIKE 3 union select * from v1;
+NOT 2 LIKE 3 NOT (2 LIKE 3) (NOT 2) LIKE 3
+1 1 0
+create or replace view v1 as select NOT 2 REGEXP 3, NOT (2 REGEXP 3), (NOT 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 regexp 3) AS `NOT 2 REGEXP 3`,!(2 regexp 3) AS `NOT (2 REGEXP 3)`,!2 regexp 3 AS `(NOT 2) REGEXP 3`
+select NOT 2 REGEXP 3, NOT (2 REGEXP 3), (NOT 2) REGEXP 3 union select * from v1;
+NOT 2 REGEXP 3 NOT (2 REGEXP 3) (NOT 2) REGEXP 3
+1 1 0
+create or replace view v1 as select NOT 2 | 3, NOT (2 | 3), (NOT 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 | 3) AS `NOT 2 | 3`,!(2 | 3) AS `NOT (2 | 3)`,!2 | 3 AS `(NOT 2) | 3`
+select NOT 2 | 3, NOT (2 | 3), (NOT 2) | 3 union select * from v1;
+NOT 2 | 3 NOT (2 | 3) (NOT 2) | 3
+0 0 3
+create or replace view v1 as select NOT 0 & 2, NOT (0 & 2), (NOT 0) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(0 & 2) AS `NOT 0 & 2`,!(0 & 2) AS `NOT (0 & 2)`,!0 & 2 AS `(NOT 0) & 2`
+select NOT 0 & 2, NOT (0 & 2), (NOT 0) & 2 union select * from v1;
+NOT 0 & 2 NOT (0 & 2) (NOT 0) & 2
+1 1 0
+create or replace view v1 as select NOT 0 << 3, NOT (0 << 3), (NOT 0) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(0 << 3) AS `NOT 0 << 3`,!(0 << 3) AS `NOT (0 << 3)`,!0 << 3 AS `(NOT 0) << 3`
+select NOT 0 << 3, NOT (0 << 3), (NOT 0) << 3 union select * from v1;
+NOT 0 << 3 NOT (0 << 3) (NOT 0) << 3
+1 1 8
+create or replace view v1 as select NOT 2 >> 3, NOT (2 >> 3), (NOT 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 >> 3) AS `NOT 2 >> 3`,!(2 >> 3) AS `NOT (2 >> 3)`,!2 >> 3 AS `(NOT 2) >> 3`
+select NOT 2 >> 3, NOT (2 >> 3), (NOT 2) >> 3 union select * from v1;
+NOT 2 >> 3 NOT (2 >> 3) (NOT 2) >> 3
+1 1 0
+create or replace view v1 as select NOT '2000-01-01' +INTERVAL 1 DAY, NOT ('2000-01-01' +INTERVAL 1 DAY), (NOT '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !('2000-01-01' + interval 1 day) AS `NOT '2000-01-01' +INTERVAL 1 DAY`,!('2000-01-01' + interval 1 day) AS `NOT ('2000-01-01' +INTERVAL 1 DAY)`,!'2000-01-01' + interval 1 day AS `(NOT '2000-01-01') +INTERVAL 1 DAY`
+select NOT '2000-01-01' +INTERVAL 1 DAY, NOT ('2000-01-01' +INTERVAL 1 DAY), (NOT '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+NOT '2000-01-01' +INTERVAL 1 DAY NOT ('2000-01-01' +INTERVAL 1 DAY) (NOT '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select NOT 2 + 3, NOT (2 + 3), (NOT 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 + 3) AS `NOT 2 + 3`,!(2 + 3) AS `NOT (2 + 3)`,!2 + 3 AS `(NOT 2) + 3`
+select NOT 2 + 3, NOT (2 + 3), (NOT 2) + 3 union select * from v1;
+NOT 2 + 3 NOT (2 + 3) (NOT 2) + 3
+0 0 3
+create or replace view v1 as select NOT 2 - 3, NOT (2 - 3), (NOT 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 - 3) AS `NOT 2 - 3`,!(2 - 3) AS `NOT (2 - 3)`,!2 - 3 AS `(NOT 2) - 3`
+select NOT 2 - 3, NOT (2 - 3), (NOT 2) - 3 union select * from v1;
+NOT 2 - 3 NOT (2 - 3) (NOT 2) - 3
+0 0 -3
+create or replace view v1 as select NOT 0 * 3, NOT (0 * 3), (NOT 0) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(0 * 3) AS `NOT 0 * 3`,!(0 * 3) AS `NOT (0 * 3)`,!0 * 3 AS `(NOT 0) * 3`
+select NOT 0 * 3, NOT (0 * 3), (NOT 0) * 3 union select * from v1;
+NOT 0 * 3 NOT (0 * 3) (NOT 0) * 3
+1 1 3
+create or replace view v1 as select NOT 0 / 3, NOT (0 / 3), (NOT 0) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(0 / 3) AS `NOT 0 / 3`,!(0 / 3) AS `NOT (0 / 3)`,!0 / 3 AS `(NOT 0) / 3`
+select NOT 0 / 3, NOT (0 / 3), (NOT 0) / 3 union select * from v1;
+NOT 0 / 3 NOT (0 / 3) (NOT 0) / 3
+1 1 0.3333
+create or replace view v1 as select NOT 2 DIV 3, NOT (2 DIV 3), (NOT 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 DIV 3) AS `NOT 2 DIV 3`,!(2 DIV 3) AS `NOT (2 DIV 3)`,!2 DIV 3 AS `(NOT 2) DIV 3`
+select NOT 2 DIV 3, NOT (2 DIV 3), (NOT 2) DIV 3 union select * from v1;
+NOT 2 DIV 3 NOT (2 DIV 3) (NOT 2) DIV 3
+1 1 0
+create or replace view v1 as select NOT 6 MOD 3, NOT (6 MOD 3), (NOT 6) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(6 MOD 3) AS `NOT 6 MOD 3`,!(6 MOD 3) AS `NOT (6 MOD 3)`,!6 MOD 3 AS `(NOT 6) MOD 3`
+select NOT 6 MOD 3, NOT (6 MOD 3), (NOT 6) MOD 3 union select * from v1;
+NOT 6 MOD 3 NOT (6 MOD 3) (NOT 6) MOD 3
+1 1 0
+create or replace view v1 as select NOT 6 % 3, NOT (6 % 3), (NOT 6) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(6 MOD 3) AS `NOT 6 % 3`,!(6 MOD 3) AS `NOT (6 % 3)`,!6 MOD 3 AS `(NOT 6) % 3`
+select NOT 6 % 3, NOT (6 % 3), (NOT 6) % 3 union select * from v1;
+NOT 6 % 3 NOT (6 % 3) (NOT 6) % 3
+1 1 0
+create or replace view v1 as select NOT 2 ^ 3, NOT (2 ^ 3), (NOT 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 ^ 3) AS `NOT 2 ^ 3`,!(2 ^ 3) AS `NOT (2 ^ 3)`,!2 ^ 3 AS `(NOT 2) ^ 3`
+select NOT 2 ^ 3, NOT (2 ^ 3), (NOT 2) ^ 3 union select * from v1;
+NOT 2 ^ 3 NOT (2 ^ 3) (NOT 2) ^ 3
+0 0 3
+create or replace view v1 as select NOT 2 BETWEEN 3 AND 4, NOT (2 BETWEEN 3 AND 4), (NOT 2) BETWEEN 3 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 not between 3 and 4 AS `NOT 2 BETWEEN 3 AND 4`,2 not between 3 and 4 AS `NOT (2 BETWEEN 3 AND 4)`,!2 between 3 and 4 AS `(NOT 2) BETWEEN 3 AND 4`
+select NOT 2 BETWEEN 3 AND 4, NOT (2 BETWEEN 3 AND 4), (NOT 2) BETWEEN 3 AND 4 union select * from v1;
+NOT 2 BETWEEN 3 AND 4 NOT (2 BETWEEN 3 AND 4) (NOT 2) BETWEEN 3 AND 4
+1 1 0
+create or replace view v1 as select - 2 IS TRUE, - (2 IS TRUE), (- 2) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 is true AS `- 2 IS TRUE`,-(2 is true) AS `- (2 IS TRUE)`,-2 is true AS `(- 2) IS TRUE`
+select - 2 IS TRUE, - (2 IS TRUE), (- 2) IS TRUE union select * from v1;
+- 2 IS TRUE - (2 IS TRUE) (- 2) IS TRUE
+1 -1 1
+create or replace view v1 as select charset(- "2" COLLATE latin1_bin), charset(- ("2" COLLATE latin1_bin)), charset((- "2") COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(-'2' collate latin1_bin) AS `charset(- "2" COLLATE latin1_bin)`,charset(-'2' collate latin1_bin) AS `charset(- ("2" COLLATE latin1_bin))`,charset((-'2') collate latin1_bin) AS `charset((- "2") COLLATE latin1_bin)`
+select charset(- "2" COLLATE latin1_bin), charset(- ("2" COLLATE latin1_bin)), charset((- "2") COLLATE latin1_bin) union select * from v1;
+charset(- "2" COLLATE latin1_bin) charset(- ("2" COLLATE latin1_bin)) charset((- "2") COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select - 2 IN (2,1), - (2 IN (2,1)), (- 2) IN (2,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 in (2,1) AS `- 2 IN (2,1)`,-(2 in (2,1)) AS `- (2 IN (2,1))`,-2 in (2,1) AS `(- 2) IN (2,1)`
+select - 2 IN (2,1), - (2 IN (2,1)), (- 2) IN (2,1) union select * from v1;
+- 2 IN (2,1) - (2 IN (2,1)) (- 2) IN (2,1)
+0 -1 0
+create or replace view v1 as select - 2 OR 3, - (2 OR 3), (- 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 or 3 AS `- 2 OR 3`,-(2 or 3) AS `- (2 OR 3)`,-2 or 3 AS `(- 2) OR 3`
+select - 2 OR 3, - (2 OR 3), (- 2) OR 3 union select * from v1;
+- 2 OR 3 - (2 OR 3) (- 2) OR 3
+1 -1 1
+create or replace view v1 as select - 2 || 3, - (2 || 3), (- 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 or 3 AS `- 2 || 3`,-(2 or 3) AS `- (2 || 3)`,-2 or 3 AS `(- 2) || 3`
+select - 2 || 3, - (2 || 3), (- 2) || 3 union select * from v1;
+- 2 || 3 - (2 || 3) (- 2) || 3
+1 -1 1
+create or replace view v1 as select - 0 XOR 3, - (0 XOR 3), (- 0) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 xor 3 AS `- 0 XOR 3`,-(0 xor 3) AS `- (0 XOR 3)`,0 xor 3 AS `(- 0) XOR 3`
+select - 0 XOR 3, - (0 XOR 3), (- 0) XOR 3 union select * from v1;
+- 0 XOR 3 - (0 XOR 3) (- 0) XOR 3
+1 -1 1
+create or replace view v1 as select - 2 AND 3, - (2 AND 3), (- 2) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 and 3 AS `- 2 AND 3`,-(2 and 3) AS `- (2 AND 3)`,-2 and 3 AS `(- 2) AND 3`
+select - 2 AND 3, - (2 AND 3), (- 2) AND 3 union select * from v1;
+- 2 AND 3 - (2 AND 3) (- 2) AND 3
+1 -1 1
+create or replace view v1 as select - 2 && 3, - (2 && 3), (- 2) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 and 3 AS `- 2 && 3`,-(2 and 3) AS `- (2 && 3)`,-2 and 3 AS `(- 2) && 3`
+select - 2 && 3, - (2 && 3), (- 2) && 3 union select * from v1;
+- 2 && 3 - (2 && 3) (- 2) && 3
+1 -1 1
+create or replace view v1 as select - 2 = 2, - (2 = 2), (- 2) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 = 2 AS `- 2 = 2`,-(2 = 2) AS `- (2 = 2)`,-2 = 2 AS `(- 2) = 2`
+select - 2 = 2, - (2 = 2), (- 2) = 2 union select * from v1;
+- 2 = 2 - (2 = 2) (- 2) = 2
+0 -1 0
+create or replace view v1 as select - 2 <=> 2, - (2 <=> 2), (- 2) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 <=> 2 AS `- 2 <=> 2`,-(2 <=> 2) AS `- (2 <=> 2)`,-2 <=> 2 AS `(- 2) <=> 2`
+select - 2 <=> 2, - (2 <=> 2), (- 2) <=> 2 union select * from v1;
+- 2 <=> 2 - (2 <=> 2) (- 2) <=> 2
+0 -1 0
+create or replace view v1 as select - 2 >= 1, - (2 >= 1), (- 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 >= 1 AS `- 2 >= 1`,-(2 >= 1) AS `- (2 >= 1)`,-2 >= 1 AS `(- 2) >= 1`
+select - 2 >= 1, - (2 >= 1), (- 2) >= 1 union select * from v1;
+- 2 >= 1 - (2 >= 1) (- 2) >= 1
+0 -1 0
+create or replace view v1 as select - 2 <= 3, - (2 <= 3), (- 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 <= 3 AS `- 2 <= 3`,-(2 <= 3) AS `- (2 <= 3)`,-2 <= 3 AS `(- 2) <= 3`
+select - 2 <= 3, - (2 <= 3), (- 2) <= 3 union select * from v1;
+- 2 <= 3 - (2 <= 3) (- 2) <= 3
+1 -1 1
+create or replace view v1 as select - 2 < 3, - (2 < 3), (- 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 < 3 AS `- 2 < 3`,-(2 < 3) AS `- (2 < 3)`,-2 < 3 AS `(- 2) < 3`
+select - 2 < 3, - (2 < 3), (- 2) < 3 union select * from v1;
+- 2 < 3 - (2 < 3) (- 2) < 3
+1 -1 1
+create or replace view v1 as select - 2 <> 3, - (2 <> 3), (- 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 <> 3 AS `- 2 <> 3`,-(2 <> 3) AS `- (2 <> 3)`,-2 <> 3 AS `(- 2) <> 3`
+select - 2 <> 3, - (2 <> 3), (- 2) <> 3 union select * from v1;
+- 2 <> 3 - (2 <> 3) (- 2) <> 3
+1 -1 1
+create or replace view v1 as select - 2 > 1, - (2 > 1), (- 2) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 > 1 AS `- 2 > 1`,-(2 > 1) AS `- (2 > 1)`,-2 > 1 AS `(- 2) > 1`
+select - 2 > 1, - (2 > 1), (- 2) > 1 union select * from v1;
+- 2 > 1 - (2 > 1) (- 2) > 1
+0 -1 0
+create or replace view v1 as select - 2 != 3, - (2 != 3), (- 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 <> 3 AS `- 2 != 3`,-(2 <> 3) AS `- (2 != 3)`,-2 <> 3 AS `(- 2) != 3`
+select - 2 != 3, - (2 != 3), (- 2) != 3 union select * from v1;
+- 2 != 3 - (2 != 3) (- 2) != 3
+1 -1 1
+create or replace view v1 as select - 2 LIKE 2, - (2 LIKE 2), (- 2) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 like 2 AS `- 2 LIKE 2`,-(2 like 2) AS `- (2 LIKE 2)`,-2 like 2 AS `(- 2) LIKE 2`
+select - 2 LIKE 2, - (2 LIKE 2), (- 2) LIKE 2 union select * from v1;
+- 2 LIKE 2 - (2 LIKE 2) (- 2) LIKE 2
+0 -1 0
+create or replace view v1 as select - 2 REGEXP 2, - (2 REGEXP 2), (- 2) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 regexp 2 AS `- 2 REGEXP 2`,-(2 regexp 2) AS `- (2 REGEXP 2)`,-2 regexp 2 AS `(- 2) REGEXP 2`
+select - 2 REGEXP 2, - (2 REGEXP 2), (- 2) REGEXP 2 union select * from v1;
+- 2 REGEXP 2 - (2 REGEXP 2) (- 2) REGEXP 2
+1 -1 1
+create or replace view v1 as select - 2 | 3, - (2 | 3), (- 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 | 3 AS `- 2 | 3`,-(2 | 3) AS `- (2 | 3)`,-2 | 3 AS `(- 2) | 3`
+select - 2 | 3, - (2 | 3), (- 2) | 3 union select * from v1;
+- 2 | 3 - (2 | 3) (- 2) | 3
+18446744073709551615 -3 18446744073709551615
+create or replace view v1 as select - 2 & 3, - (2 & 3), (- 2) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 & 3 AS `- 2 & 3`,-(2 & 3) AS `- (2 & 3)`,-2 & 3 AS `(- 2) & 3`
+select - 2 & 3, - (2 & 3), (- 2) & 3 union select * from v1;
+- 2 & 3 - (2 & 3) (- 2) & 3
+2 -2 2
+create or replace view v1 as select - 2 << 3, - (2 << 3), (- 2) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 << 3 AS `- 2 << 3`,-(2 << 3) AS `- (2 << 3)`,-2 << 3 AS `(- 2) << 3`
+select - 2 << 3, - (2 << 3), (- 2) << 3 union select * from v1;
+- 2 << 3 - (2 << 3) (- 2) << 3
+18446744073709551600 -16 18446744073709551600
+create or replace view v1 as select - 2 >> 3, - (2 >> 3), (- 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 >> 3 AS `- 2 >> 3`,-(2 >> 3) AS `- (2 >> 3)`,-2 >> 3 AS `(- 2) >> 3`
+select - 2 >> 3, - (2 >> 3), (- 2) >> 3 union select * from v1;
+- 2 >> 3 - (2 >> 3) (- 2) >> 3
+2305843009213693951 0 2305843009213693951
+create or replace view v1 as select - '2000-01-01' +INTERVAL 1 DAY, - ('2000-01-01' +INTERVAL 1 DAY), (- '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -'2000-01-01' + interval 1 day AS `- '2000-01-01' +INTERVAL 1 DAY`,-('2000-01-01' + interval 1 day) AS `- ('2000-01-01' +INTERVAL 1 DAY)`,-'2000-01-01' + interval 1 day AS `(- '2000-01-01') +INTERVAL 1 DAY`
+select - '2000-01-01' +INTERVAL 1 DAY, - ('2000-01-01' +INTERVAL 1 DAY), (- '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+- '2000-01-01' +INTERVAL 1 DAY - ('2000-01-01' +INTERVAL 1 DAY) (- '2000-01-01') +INTERVAL 1 DAY
+NULL -20000102 NULL
+create or replace view v1 as select - 2 + 3, - (2 + 3), (- 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 + 3 AS `- 2 + 3`,-(2 + 3) AS `- (2 + 3)`,-2 + 3 AS `(- 2) + 3`
+select - 2 + 3, - (2 + 3), (- 2) + 3 union select * from v1;
+- 2 + 3 - (2 + 3) (- 2) + 3
+1 -5 1
+create or replace view v1 as select - 2 - 3, - (2 - 3), (- 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 - 3 AS `- 2 - 3`,-(2 - 3) AS `- (2 - 3)`,-2 - 3 AS `(- 2) - 3`
+select - 2 - 3, - (2 - 3), (- 2) - 3 union select * from v1;
+- 2 - 3 - (2 - 3) (- 2) - 3
+-5 1 -5
+create or replace view v1 as select - 2 ^ 3, - (2 ^ 3), (- 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 ^ 3 AS `- 2 ^ 3`,-(2 ^ 3) AS `- (2 ^ 3)`,-2 ^ 3 AS `(- 2) ^ 3`
+select - 2 ^ 3, - (2 ^ 3), (- 2) ^ 3 union select * from v1;
+- 2 ^ 3 - (2 ^ 3) (- 2) ^ 3
+18446744073709551613 -1 18446744073709551613
+create or replace view v1 as select - 2 BETWEEN 1 AND 3, - (2 BETWEEN 1 AND 3), (- 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 between 1 and 3 AS `- 2 BETWEEN 1 AND 3`,-(2 between 1 and 3) AS `- (2 BETWEEN 1 AND 3)`,-2 between 1 and 3 AS `(- 2) BETWEEN 1 AND 3`
+select - 2 BETWEEN 1 AND 3, - (2 BETWEEN 1 AND 3), (- 2) BETWEEN 1 AND 3 union select * from v1;
+- 2 BETWEEN 1 AND 3 - (2 BETWEEN 1 AND 3) (- 2) BETWEEN 1 AND 3
+0 -1 0
+create or replace view v1 as select ~ 2 IS TRUE, ~ (2 IS TRUE), (~ 2) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 is true AS `~ 2 IS TRUE`,~(2 is true) AS `~ (2 IS TRUE)`,~2 is true AS `(~ 2) IS TRUE`
+select ~ 2 IS TRUE, ~ (2 IS TRUE), (~ 2) IS TRUE union select * from v1;
+~ 2 IS TRUE ~ (2 IS TRUE) (~ 2) IS TRUE
+1 18446744073709551614 1
+create or replace view v1 as select charset(~ 2 COLLATE latin1_bin), charset(~ (2 COLLATE latin1_bin)), charset((~ 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(~2 collate latin1_bin) AS `charset(~ 2 COLLATE latin1_bin)`,charset(~2 collate latin1_bin) AS `charset(~ (2 COLLATE latin1_bin))`,charset((~2) collate latin1_bin) AS `charset((~ 2) COLLATE latin1_bin)`
+select charset(~ 2 COLLATE latin1_bin), charset(~ (2 COLLATE latin1_bin)), charset((~ 2) COLLATE latin1_bin) union select * from v1;
+charset(~ 2 COLLATE latin1_bin) charset(~ (2 COLLATE latin1_bin)) charset((~ 2) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select ~ 2 IN (0,1), ~ (2 IN (0,1)), (~ 2) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 in (0,1) AS `~ 2 IN (0,1)`,~(2 in (0,1)) AS `~ (2 IN (0,1))`,~2 in (0,1) AS `(~ 2) IN (0,1)`
+select ~ 2 IN (0,1), ~ (2 IN (0,1)), (~ 2) IN (0,1) union select * from v1;
+~ 2 IN (0,1) ~ (2 IN (0,1)) (~ 2) IN (0,1)
+0 18446744073709551615 0
+create or replace view v1 as select ~ 2 OR 3, ~ (2 OR 3), (~ 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 or 3 AS `~ 2 OR 3`,~(2 or 3) AS `~ (2 OR 3)`,~2 or 3 AS `(~ 2) OR 3`
+select ~ 2 OR 3, ~ (2 OR 3), (~ 2) OR 3 union select * from v1;
+~ 2 OR 3 ~ (2 OR 3) (~ 2) OR 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 or 3 AS `~ 2 || 3`,~(2 or 3) AS `~ (2 || 3)`,~2 or 3 AS `(~ 2) || 3`
+select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3 union select * from v1;
+~ 2 || 3 ~ (2 || 3) (~ 2) || 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 XOR 3, ~ (2 XOR 3), (~ 2) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 xor 3 AS `~ 2 XOR 3`,~(2 xor 3) AS `~ (2 XOR 3)`,~2 xor 3 AS `(~ 2) XOR 3`
+select ~ 2 XOR 3, ~ (2 XOR 3), (~ 2) XOR 3 union select * from v1;
+~ 2 XOR 3 ~ (2 XOR 3) (~ 2) XOR 3
+0 18446744073709551615 0
+create or replace view v1 as select ~ 2 AND 3, ~ (2 AND 3), (~ 2) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 and 3 AS `~ 2 AND 3`,~(2 and 3) AS `~ (2 AND 3)`,~2 and 3 AS `(~ 2) AND 3`
+select ~ 2 AND 3, ~ (2 AND 3), (~ 2) AND 3 union select * from v1;
+~ 2 AND 3 ~ (2 AND 3) (~ 2) AND 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 && 3, ~ (2 && 3), (~ 2) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 and 3 AS `~ 2 && 3`,~(2 and 3) AS `~ (2 && 3)`,~2 and 3 AS `(~ 2) && 3`
+select ~ 2 && 3, ~ (2 && 3), (~ 2) && 3 union select * from v1;
+~ 2 && 3 ~ (2 && 3) (~ 2) && 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 = 3, ~ (2 = 3), (~ 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 = 3 AS `~ 2 = 3`,~(2 = 3) AS `~ (2 = 3)`,~2 = 3 AS `(~ 2) = 3`
+select ~ 2 = 3, ~ (2 = 3), (~ 2) = 3 union select * from v1;
+~ 2 = 3 ~ (2 = 3) (~ 2) = 3
+0 18446744073709551615 0
+create or replace view v1 as select ~ 2 <=> 3, ~ (2 <=> 3), (~ 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 <=> 3 AS `~ 2 <=> 3`,~(2 <=> 3) AS `~ (2 <=> 3)`,~2 <=> 3 AS `(~ 2) <=> 3`
+select ~ 2 <=> 3, ~ (2 <=> 3), (~ 2) <=> 3 union select * from v1;
+~ 2 <=> 3 ~ (2 <=> 3) (~ 2) <=> 3
+0 18446744073709551615 0
+create or replace view v1 as select ~ 2 >= 3, ~ (2 >= 3), (~ 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 >= 3 AS `~ 2 >= 3`,~(2 >= 3) AS `~ (2 >= 3)`,~2 >= 3 AS `(~ 2) >= 3`
+select ~ 2 >= 3, ~ (2 >= 3), (~ 2) >= 3 union select * from v1;
+~ 2 >= 3 ~ (2 >= 3) (~ 2) >= 3
+1 18446744073709551615 1
+create or replace view v1 as select ~ 2 <= 3, ~ (2 <= 3), (~ 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 <= 3 AS `~ 2 <= 3`,~(2 <= 3) AS `~ (2 <= 3)`,~2 <= 3 AS `(~ 2) <= 3`
+select ~ 2 <= 3, ~ (2 <= 3), (~ 2) <= 3 union select * from v1;
+~ 2 <= 3 ~ (2 <= 3) (~ 2) <= 3
+0 18446744073709551614 0
+create or replace view v1 as select ~ 2 < 3, ~ (2 < 3), (~ 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 < 3 AS `~ 2 < 3`,~(2 < 3) AS `~ (2 < 3)`,~2 < 3 AS `(~ 2) < 3`
+select ~ 2 < 3, ~ (2 < 3), (~ 2) < 3 union select * from v1;
+~ 2 < 3 ~ (2 < 3) (~ 2) < 3
+0 18446744073709551614 0
+create or replace view v1 as select ~ 2 <> 3, ~ (2 <> 3), (~ 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 <> 3 AS `~ 2 <> 3`,~(2 <> 3) AS `~ (2 <> 3)`,~2 <> 3 AS `(~ 2) <> 3`
+select ~ 2 <> 3, ~ (2 <> 3), (~ 2) <> 3 union select * from v1;
+~ 2 <> 3 ~ (2 <> 3) (~ 2) <> 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 > 3, ~ (2 > 3), (~ 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 > 3 AS `~ 2 > 3`,~(2 > 3) AS `~ (2 > 3)`,~2 > 3 AS `(~ 2) > 3`
+select ~ 2 > 3, ~ (2 > 3), (~ 2) > 3 union select * from v1;
+~ 2 > 3 ~ (2 > 3) (~ 2) > 3
+1 18446744073709551615 1
+create or replace view v1 as select ~ 2 != 3, ~ (2 != 3), (~ 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 <> 3 AS `~ 2 != 3`,~(2 <> 3) AS `~ (2 != 3)`,~2 <> 3 AS `(~ 2) != 3`
+select ~ 2 != 3, ~ (2 != 3), (~ 2) != 3 union select * from v1;
+~ 2 != 3 ~ (2 != 3) (~ 2) != 3
+1 18446744073709551614 1
+create or replace view v1 as select ~ 2 LIKE 3, ~ (2 LIKE 3), (~ 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 like 3 AS `~ 2 LIKE 3`,~(2 like 3) AS `~ (2 LIKE 3)`,~2 like 3 AS `(~ 2) LIKE 3`
+select ~ 2 LIKE 3, ~ (2 LIKE 3), (~ 2) LIKE 3 union select * from v1;
+~ 2 LIKE 3 ~ (2 LIKE 3) (~ 2) LIKE 3
+0 18446744073709551615 0
+create or replace view v1 as select ~ 2 REGEXP 3, ~ (2 REGEXP 3), (~ 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 regexp 3 AS `~ 2 REGEXP 3`,~(2 regexp 3) AS `~ (2 REGEXP 3)`,~2 regexp 3 AS `(~ 2) REGEXP 3`
+select ~ 2 REGEXP 3, ~ (2 REGEXP 3), (~ 2) REGEXP 3 union select * from v1;
+~ 2 REGEXP 3 ~ (2 REGEXP 3) (~ 2) REGEXP 3
+1 18446744073709551615 1
+create or replace view v1 as select ~ 2 | 3, ~ (2 | 3), (~ 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 | 3 AS `~ 2 | 3`,~(2 | 3) AS `~ (2 | 3)`,~2 | 3 AS `(~ 2) | 3`
+select ~ 2 | 3, ~ (2 | 3), (~ 2) | 3 union select * from v1;
+~ 2 | 3 ~ (2 | 3) (~ 2) | 3
+18446744073709551615 18446744073709551612 18446744073709551615
+create or replace view v1 as select ~ 2 & 3, ~ (2 & 3), (~ 2) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 & 3 AS `~ 2 & 3`,~(2 & 3) AS `~ (2 & 3)`,~2 & 3 AS `(~ 2) & 3`
+select ~ 2 & 3, ~ (2 & 3), (~ 2) & 3 union select * from v1;
+~ 2 & 3 ~ (2 & 3) (~ 2) & 3
+1 18446744073709551613 1
+create or replace view v1 as select ~ 2 << 3, ~ (2 << 3), (~ 2) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 << 3 AS `~ 2 << 3`,~(2 << 3) AS `~ (2 << 3)`,~2 << 3 AS `(~ 2) << 3`
+select ~ 2 << 3, ~ (2 << 3), (~ 2) << 3 union select * from v1;
+~ 2 << 3 ~ (2 << 3) (~ 2) << 3
+18446744073709551592 18446744073709551599 18446744073709551592
+create or replace view v1 as select ~ 2 >> 3, ~ (2 >> 3), (~ 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 >> 3 AS `~ 2 >> 3`,~(2 >> 3) AS `~ (2 >> 3)`,~2 >> 3 AS `(~ 2) >> 3`
+select ~ 2 >> 3, ~ (2 >> 3), (~ 2) >> 3 union select * from v1;
+~ 2 >> 3 ~ (2 >> 3) (~ 2) >> 3
+2305843009213693951 18446744073709551615 2305843009213693951
+create or replace view v1 as select ~ '2000-01-01' +INTERVAL 1 DAY, ~ ('2000-01-01' +INTERVAL 1 DAY), (~ '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~'2000-01-01' + interval 1 day AS `~ '2000-01-01' +INTERVAL 1 DAY`,~('2000-01-01' + interval 1 day) AS `~ ('2000-01-01' +INTERVAL 1 DAY)`,~'2000-01-01' + interval 1 day AS `(~ '2000-01-01') +INTERVAL 1 DAY`
+select ~ '2000-01-01' +INTERVAL 1 DAY, ~ ('2000-01-01' +INTERVAL 1 DAY), (~ '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+~ '2000-01-01' +INTERVAL 1 DAY ~ ('2000-01-01' +INTERVAL 1 DAY) (~ '2000-01-01') +INTERVAL 1 DAY
+NULL 18446744073689551513 NULL
+create or replace view v1 as select ~ 10000 + 3, ~ (10000 + 3), (~ 10000) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~10000 + 3 AS `~ 10000 + 3`,~(10000 + 3) AS `~ (10000 + 3)`,~10000 + 3 AS `(~ 10000) + 3`
+select ~ 10000 + 3, ~ (10000 + 3), (~ 10000) + 3 union select * from v1;
+~ 10000 + 3 ~ (10000 + 3) (~ 10000) + 3
+18446744073709541618 18446744073709541612 18446744073709541618
+create or replace view v1 as select ~ 2 - 3, ~ (2 - 3), (~ 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 - 3 AS `~ 2 - 3`,~(2 - 3) AS `~ (2 - 3)`,~2 - 3 AS `(~ 2) - 3`
+select ~ 2 - 3, ~ (2 - 3), (~ 2) - 3 union select * from v1;
+~ 2 - 3 ~ (2 - 3) (~ 2) - 3
+18446744073709551610 0 18446744073709551610
+create or replace view v1 as select ~ 10000000000000000000 * 2, ~ (100 * 2), (~ 10000000000000000000) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~10000000000000000000 * 2 AS `~ 10000000000000000000 * 2`,~(100 * 2) AS `~ (100 * 2)`,~10000000000000000000 * 2 AS `(~ 10000000000000000000) * 2`
+select ~ 10000000000000000000 * 2, ~ (100 * 2), (~ 10000000000000000000) * 2 union select * from v1;
+~ 10000000000000000000 * 2 ~ (100 * 2) (~ 10000000000000000000) * 2
+16893488147419103230 18446744073709551415 16893488147419103230
+create or replace view v1 as select ~ 2 / 3, ~ (2 / 3), (~ 2) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 / 3 AS `~ 2 / 3`,~(2 / 3) AS `~ (2 / 3)`,~2 / 3 AS `(~ 2) / 3`
+select ~ 2 / 3, ~ (2 / 3), (~ 2) / 3 union select * from v1;
+~ 2 / 3 ~ (2 / 3) (~ 2) / 3
+6148914691236517204.3333 18446744073709551614 6148914691236517204.3333
+create or replace view v1 as select ~ 2 DIV 3, ~ (2 DIV 3), (~ 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 DIV 3 AS `~ 2 DIV 3`,~(2 DIV 3) AS `~ (2 DIV 3)`,~2 DIV 3 AS `(~ 2) DIV 3`
+select ~ 2 DIV 3, ~ (2 DIV 3), (~ 2) DIV 3 union select * from v1;
+~ 2 DIV 3 ~ (2 DIV 3) (~ 2) DIV 3
+6148914691236517204 18446744073709551615 6148914691236517204
+create or replace view v1 as select ~ 2 MOD 3, ~ (2 MOD 3), (~ 2) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 MOD 3 AS `~ 2 MOD 3`,~(2 MOD 3) AS `~ (2 MOD 3)`,~2 MOD 3 AS `(~ 2) MOD 3`
+select ~ 2 MOD 3, ~ (2 MOD 3), (~ 2) MOD 3 union select * from v1;
+~ 2 MOD 3 ~ (2 MOD 3) (~ 2) MOD 3
+1 18446744073709551613 1
+create or replace view v1 as select ~ 2 % 3, ~ (2 % 3), (~ 2) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 MOD 3 AS `~ 2 % 3`,~(2 MOD 3) AS `~ (2 % 3)`,~2 MOD 3 AS `(~ 2) % 3`
+select ~ 2 % 3, ~ (2 % 3), (~ 2) % 3 union select * from v1;
+~ 2 % 3 ~ (2 % 3) (~ 2) % 3
+1 18446744073709551613 1
+create or replace view v1 as select ~ 2 BETWEEN 1 AND 3, ~ (2 BETWEEN 1 AND 3), (~ 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 between 1 and 3 AS `~ 2 BETWEEN 1 AND 3`,~(2 between 1 and 3) AS `~ (2 BETWEEN 1 AND 3)`,~2 between 1 and 3 AS `(~ 2) BETWEEN 1 AND 3`
+select ~ 2 BETWEEN 1 AND 3, ~ (2 BETWEEN 1 AND 3), (~ 2) BETWEEN 1 AND 3 union select * from v1;
+~ 2 BETWEEN 1 AND 3 ~ (2 BETWEEN 1 AND 3) (~ 2) BETWEEN 1 AND 3
+0 18446744073709551614 0
+create or replace view v1 as select charset(! 2 COLLATE latin1_bin), charset(! (2 COLLATE latin1_bin)), charset((! 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(!2 collate latin1_bin) AS `charset(! 2 COLLATE latin1_bin)`,charset(!2 collate latin1_bin) AS `charset(! (2 COLLATE latin1_bin))`,charset((!2) collate latin1_bin) AS `charset((! 2) COLLATE latin1_bin)`
+select charset(! 2 COLLATE latin1_bin), charset(! (2 COLLATE latin1_bin)), charset((! 2) COLLATE latin1_bin) union select * from v1;
+charset(! 2 COLLATE latin1_bin) charset(! (2 COLLATE latin1_bin)) charset((! 2) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select ! 2 IN (0,2), ! (2 IN (0,2)), (! 2) IN (0,2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 in (0,2) AS `! 2 IN (0,2)`,2 not in (0,2) AS `! (2 IN (0,2))`,!2 in (0,2) AS `(! 2) IN (0,2)`
+select ! 2 IN (0,2), ! (2 IN (0,2)), (! 2) IN (0,2) union select * from v1;
+! 2 IN (0,2) ! (2 IN (0,2)) (! 2) IN (0,2)
+1 0 1
+create or replace view v1 as select ! 2 OR 3, ! (2 OR 3), (! 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 or 3 AS `! 2 OR 3`,!2 and !3 AS `! (2 OR 3)`,!2 or 3 AS `(! 2) OR 3`
+select ! 2 OR 3, ! (2 OR 3), (! 2) OR 3 union select * from v1;
+! 2 OR 3 ! (2 OR 3) (! 2) OR 3
+1 0 1
+create or replace view v1 as select ! 2 || 3, ! (2 || 3), (! 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 or 3 AS `! 2 || 3`,!2 and !3 AS `! (2 || 3)`,!2 or 3 AS `(! 2) || 3`
+select ! 2 || 3, ! (2 || 3), (! 2) || 3 union select * from v1;
+! 2 || 3 ! (2 || 3) (! 2) || 3
+1 0 1
+create or replace view v1 as select ! 2 AND 0, ! (2 AND 0), (! 2) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 and 0 AS `! 2 AND 0`,!2 or !0 AS `! (2 AND 0)`,!2 and 0 AS `(! 2) AND 0`
+select ! 2 AND 0, ! (2 AND 0), (! 2) AND 0 union select * from v1;
+! 2 AND 0 ! (2 AND 0) (! 2) AND 0
+0 1 0
+create or replace view v1 as select ! 2 && 0, ! (2 && 0), (! 2) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 and 0 AS `! 2 && 0`,!2 or !0 AS `! (2 && 0)`,!2 and 0 AS `(! 2) && 0`
+select ! 2 && 0, ! (2 && 0), (! 2) && 0 union select * from v1;
+! 2 && 0 ! (2 && 0) (! 2) && 0
+0 1 0
+create or replace view v1 as select ! 2 = 3, ! (2 = 3), (! 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 = 3 AS `! 2 = 3`,2 <> 3 AS `! (2 = 3)`,!2 = 3 AS `(! 2) = 3`
+select ! 2 = 3, ! (2 = 3), (! 2) = 3 union select * from v1;
+! 2 = 3 ! (2 = 3) (! 2) = 3
+0 1 0
+create or replace view v1 as select ! 2 <=> 3, ! (2 <=> 3), (! 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 <=> 3 AS `! 2 <=> 3`,!(2 <=> 3) AS `! (2 <=> 3)`,!2 <=> 3 AS `(! 2) <=> 3`
+select ! 2 <=> 3, ! (2 <=> 3), (! 2) <=> 3 union select * from v1;
+! 2 <=> 3 ! (2 <=> 3) (! 2) <=> 3
+0 1 0
+create or replace view v1 as select ! 2 >= 3, ! (2 >= 3), (! 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 >= 3 AS `! 2 >= 3`,2 < 3 AS `! (2 >= 3)`,!2 >= 3 AS `(! 2) >= 3`
+select ! 2 >= 3, ! (2 >= 3), (! 2) >= 3 union select * from v1;
+! 2 >= 3 ! (2 >= 3) (! 2) >= 3
+0 1 0
+create or replace view v1 as select ! 2 <= 3, ! (2 <= 3), (! 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 <= 3 AS `! 2 <= 3`,2 > 3 AS `! (2 <= 3)`,!2 <= 3 AS `(! 2) <= 3`
+select ! 2 <= 3, ! (2 <= 3), (! 2) <= 3 union select * from v1;
+! 2 <= 3 ! (2 <= 3) (! 2) <= 3
+1 0 1
+create or replace view v1 as select ! 2 < 3, ! (2 < 3), (! 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 < 3 AS `! 2 < 3`,2 >= 3 AS `! (2 < 3)`,!2 < 3 AS `(! 2) < 3`
+select ! 2 < 3, ! (2 < 3), (! 2) < 3 union select * from v1;
+! 2 < 3 ! (2 < 3) (! 2) < 3
+1 0 1
+create or replace view v1 as select ! 2 <> 3, ! (2 <> 3), (! 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 <> 3 AS `! 2 <> 3`,2 = 3 AS `! (2 <> 3)`,!2 <> 3 AS `(! 2) <> 3`
+select ! 2 <> 3, ! (2 <> 3), (! 2) <> 3 union select * from v1;
+! 2 <> 3 ! (2 <> 3) (! 2) <> 3
+1 0 1
+create or replace view v1 as select ! 2 > 3, ! (2 > 3), (! 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 > 3 AS `! 2 > 3`,2 <= 3 AS `! (2 > 3)`,!2 > 3 AS `(! 2) > 3`
+select ! 2 > 3, ! (2 > 3), (! 2) > 3 union select * from v1;
+! 2 > 3 ! (2 > 3) (! 2) > 3
+0 1 0
+create or replace view v1 as select ! 2 != 3, ! (2 != 3), (! 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 <> 3 AS `! 2 != 3`,2 = 3 AS `! (2 != 3)`,!2 <> 3 AS `(! 2) != 3`
+select ! 2 != 3, ! (2 != 3), (! 2) != 3 union select * from v1;
+! 2 != 3 ! (2 != 3) (! 2) != 3
+1 0 1
+create or replace view v1 as select ! 2 LIKE 3, ! (2 LIKE 3), (! 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 like 3 AS `! 2 LIKE 3`,2 not like 3 AS `! (2 LIKE 3)`,!2 like 3 AS `(! 2) LIKE 3`
+select ! 2 LIKE 3, ! (2 LIKE 3), (! 2) LIKE 3 union select * from v1;
+! 2 LIKE 3 ! (2 LIKE 3) (! 2) LIKE 3
+0 1 0
+create or replace view v1 as select ! 2 REGEXP 3, ! (2 REGEXP 3), (! 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 regexp 3 AS `! 2 REGEXP 3`,!(2 regexp 3) AS `! (2 REGEXP 3)`,!2 regexp 3 AS `(! 2) REGEXP 3`
+select ! 2 REGEXP 3, ! (2 REGEXP 3), (! 2) REGEXP 3 union select * from v1;
+! 2 REGEXP 3 ! (2 REGEXP 3) (! 2) REGEXP 3
+0 1 0
+create or replace view v1 as select ! 2 | 3, ! (2 | 3), (! 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 | 3 AS `! 2 | 3`,!(2 | 3) AS `! (2 | 3)`,!2 | 3 AS `(! 2) | 3`
+select ! 2 | 3, ! (2 | 3), (! 2) | 3 union select * from v1;
+! 2 | 3 ! (2 | 3) (! 2) | 3
+3 0 3
+create or replace view v1 as select ! 2 & 0, ! (2 & 0), (! 2) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 & 0 AS `! 2 & 0`,!(2 & 0) AS `! (2 & 0)`,!2 & 0 AS `(! 2) & 0`
+select ! 2 & 0, ! (2 & 0), (! 2) & 0 union select * from v1;
+! 2 & 0 ! (2 & 0) (! 2) & 0
+0 1 0
+create or replace view v1 as select ! 0 << 3, ! (0 << 3), (! 0) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !0 << 3 AS `! 0 << 3`,!(0 << 3) AS `! (0 << 3)`,!0 << 3 AS `(! 0) << 3`
+select ! 0 << 3, ! (0 << 3), (! 0) << 3 union select * from v1;
+! 0 << 3 ! (0 << 3) (! 0) << 3
+8 1 8
+create or replace view v1 as select ! 2 >> 3, ! (2 >> 3), (! 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 >> 3 AS `! 2 >> 3`,!(2 >> 3) AS `! (2 >> 3)`,!2 >> 3 AS `(! 2) >> 3`
+select ! 2 >> 3, ! (2 >> 3), (! 2) >> 3 union select * from v1;
+! 2 >> 3 ! (2 >> 3) (! 2) >> 3
+0 1 0
+create or replace view v1 as select ! '2000-01-01' +INTERVAL 1 DAY, ! ('2000-01-01' +INTERVAL 1 DAY), (! '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !'2000-01-01' + interval 1 day AS `! '2000-01-01' +INTERVAL 1 DAY`,!('2000-01-01' + interval 1 day) AS `! ('2000-01-01' +INTERVAL 1 DAY)`,!'2000-01-01' + interval 1 day AS `(! '2000-01-01') +INTERVAL 1 DAY`
+select ! '2000-01-01' +INTERVAL 1 DAY, ! ('2000-01-01' +INTERVAL 1 DAY), (! '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+! '2000-01-01' +INTERVAL 1 DAY ! ('2000-01-01' +INTERVAL 1 DAY) (! '2000-01-01') +INTERVAL 1 DAY
+NULL 0 NULL
+create or replace view v1 as select ! 2 + 3, ! (2 + 3), (! 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 + 3 AS `! 2 + 3`,!(2 + 3) AS `! (2 + 3)`,!2 + 3 AS `(! 2) + 3`
+select ! 2 + 3, ! (2 + 3), (! 2) + 3 union select * from v1;
+! 2 + 3 ! (2 + 3) (! 2) + 3
+3 0 3
+create or replace view v1 as select ! 2 - 3, ! (2 - 3), (! 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 - 3 AS `! 2 - 3`,!(2 - 3) AS `! (2 - 3)`,!2 - 3 AS `(! 2) - 3`
+select ! 2 - 3, ! (2 - 3), (! 2) - 3 union select * from v1;
+! 2 - 3 ! (2 - 3) (! 2) - 3
+-3 0 -3
+create or replace view v1 as select ! 0 * 3, ! (0 * 3), (! 0) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !0 * 3 AS `! 0 * 3`,!(0 * 3) AS `! (0 * 3)`,!0 * 3 AS `(! 0) * 3`
+select ! 0 * 3, ! (0 * 3), (! 0) * 3 union select * from v1;
+! 0 * 3 ! (0 * 3) (! 0) * 3
+3 1 3
+create or replace view v1 as select ! 0 / 3, ! (0 / 3), (! 0) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !0 / 3 AS `! 0 / 3`,!(0 / 3) AS `! (0 / 3)`,!0 / 3 AS `(! 0) / 3`
+select ! 0 / 3, ! (0 / 3), (! 0) / 3 union select * from v1;
+! 0 / 3 ! (0 / 3) (! 0) / 3
+0.3333 1 0.3333
+create or replace view v1 as select ! 2 DIV 3, ! (2 DIV 3), (! 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 DIV 3 AS `! 2 DIV 3`,!(2 DIV 3) AS `! (2 DIV 3)`,!2 DIV 3 AS `(! 2) DIV 3`
+select ! 2 DIV 3, ! (2 DIV 3), (! 2) DIV 3 union select * from v1;
+! 2 DIV 3 ! (2 DIV 3) (! 2) DIV 3
+0 1 0
+create or replace view v1 as select ! 6 MOD 3, ! (6 MOD 3), (! 6) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !6 MOD 3 AS `! 6 MOD 3`,!(6 MOD 3) AS `! (6 MOD 3)`,!6 MOD 3 AS `(! 6) MOD 3`
+select ! 6 MOD 3, ! (6 MOD 3), (! 6) MOD 3 union select * from v1;
+! 6 MOD 3 ! (6 MOD 3) (! 6) MOD 3
+0 1 0
+create or replace view v1 as select ! 6 % 3, ! (6 % 3), (! 6) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !6 MOD 3 AS `! 6 % 3`,!(6 MOD 3) AS `! (6 % 3)`,!6 MOD 3 AS `(! 6) % 3`
+select ! 6 % 3, ! (6 % 3), (! 6) % 3 union select * from v1;
+! 6 % 3 ! (6 % 3) (! 6) % 3
+0 1 0
+create or replace view v1 as select ! 2 ^ 3, ! (2 ^ 3), (! 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 ^ 3 AS `! 2 ^ 3`,!(2 ^ 3) AS `! (2 ^ 3)`,!2 ^ 3 AS `(! 2) ^ 3`
+select ! 2 ^ 3, ! (2 ^ 3), (! 2) ^ 3 union select * from v1;
+! 2 ^ 3 ! (2 ^ 3) (! 2) ^ 3
+3 0 3
+create or replace view v1 as select ! 2 BETWEEN 3 AND 4, ! (2 BETWEEN 3 AND 4), (! 2) BETWEEN 3 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 between 3 and 4 AS `! 2 BETWEEN 3 AND 4`,2 not between 3 and 4 AS `! (2 BETWEEN 3 AND 4)`,!2 between 3 and 4 AS `(! 2) BETWEEN 3 AND 4`
+select ! 2 BETWEEN 3 AND 4, ! (2 BETWEEN 3 AND 4), (! 2) BETWEEN 3 AND 4 union select * from v1;
+! 2 BETWEEN 3 AND 4 ! (2 BETWEEN 3 AND 4) (! 2) BETWEEN 3 AND 4
+0 1 0
+create or replace view v1 as select CHARSET(BINARY '2' COLLATE latin1_bin), CHARSET(BINARY ('2' COLLATE latin1_bin)), 'error'/*CHARSET((BINARY '2') COLLATE latin1_bin)*/;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(cast('2' collate latin1_bin as char charset binary)) AS `CHARSET(BINARY '2' COLLATE latin1_bin)`,charset(cast('2' collate latin1_bin as char charset binary)) AS `CHARSET(BINARY ('2' COLLATE latin1_bin))`,'error' AS `error`
+select CHARSET(BINARY '2' COLLATE latin1_bin), CHARSET(BINARY ('2' COLLATE latin1_bin)), 'error'/*CHARSET((BINARY '2') COLLATE latin1_bin)*/ union select * from v1;
+CHARSET(BINARY '2' COLLATE latin1_bin) CHARSET(BINARY ('2' COLLATE latin1_bin)) error
+binary binary error
+create or replace view v1 as select BINARY 'c' IN ('C','X'), BINARY ('c' IN ('C','X')), (BINARY 'c') IN ('C','X');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) in ('C','X') AS `BINARY 'c' IN ('C','X')`,cast('c' in ('C','X') as char charset binary) AS `BINARY ('c' IN ('C','X'))`,cast('c' as char charset binary) in ('C','X') AS `(BINARY 'c') IN ('C','X')`
+select BINARY 'c' IN ('C','X'), BINARY ('c' IN ('C','X')), (BINARY 'c') IN ('C','X') union select * from v1;
+BINARY 'c' IN ('C','X') BINARY ('c' IN ('C','X')) (BINARY 'c') IN ('C','X')
+0 1 0
+create or replace view v1 as select BINARY 'c' = 'C', BINARY ('c' = 'C'), (BINARY 'c') = 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) = 'C' AS `BINARY 'c' = 'C'`,cast('c' = 'C' as char charset binary) AS `BINARY ('c' = 'C')`,cast('c' as char charset binary) = 'C' AS `(BINARY 'c') = 'C'`
+select BINARY 'c' = 'C', BINARY ('c' = 'C'), (BINARY 'c') = 'C' union select * from v1;
+BINARY 'c' = 'C' BINARY ('c' = 'C') (BINARY 'c') = 'C'
+0 1 0
+create or replace view v1 as select BINARY 'c' <=> 'C', BINARY ('c' <=> 'C'), (BINARY 'c') <=> 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) <=> 'C' AS `BINARY 'c' <=> 'C'`,cast('c' <=> 'C' as char charset binary) AS `BINARY ('c' <=> 'C')`,cast('c' as char charset binary) <=> 'C' AS `(BINARY 'c') <=> 'C'`
+select BINARY 'c' <=> 'C', BINARY ('c' <=> 'C'), (BINARY 'c') <=> 'C' union select * from v1;
+BINARY 'c' <=> 'C' BINARY ('c' <=> 'C') (BINARY 'c') <=> 'C'
+0 1 0
+create or replace view v1 as select BINARY 'c' >= 'D', BINARY ('c' >= 'D'), (BINARY 'c') >= 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) >= 'D' AS `BINARY 'c' >= 'D'`,cast('c' >= 'D' as char charset binary) AS `BINARY ('c' >= 'D')`,cast('c' as char charset binary) >= 'D' AS `(BINARY 'c') >= 'D'`
+select BINARY 'c' >= 'D', BINARY ('c' >= 'D'), (BINARY 'c') >= 'D' union select * from v1;
+BINARY 'c' >= 'D' BINARY ('c' >= 'D') (BINARY 'c') >= 'D'
+1 0 1
+create or replace view v1 as select BINARY 'c' <= 'C', BINARY ('c' <= 'C'), (BINARY 'c') <= 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) <= 'C' AS `BINARY 'c' <= 'C'`,cast('c' <= 'C' as char charset binary) AS `BINARY ('c' <= 'C')`,cast('c' as char charset binary) <= 'C' AS `(BINARY 'c') <= 'C'`
+select BINARY 'c' <= 'C', BINARY ('c' <= 'C'), (BINARY 'c') <= 'C' union select * from v1;
+BINARY 'c' <= 'C' BINARY ('c' <= 'C') (BINARY 'c') <= 'C'
+0 1 0
+create or replace view v1 as select BINARY 'c' < 'D', BINARY ('c' < 'D'), (BINARY 'c') < 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) < 'D' AS `BINARY 'c' < 'D'`,cast('c' < 'D' as char charset binary) AS `BINARY ('c' < 'D')`,cast('c' as char charset binary) < 'D' AS `(BINARY 'c') < 'D'`
+select BINARY 'c' < 'D', BINARY ('c' < 'D'), (BINARY 'c') < 'D' union select * from v1;
+BINARY 'c' < 'D' BINARY ('c' < 'D') (BINARY 'c') < 'D'
+0 1 0
+create or replace view v1 as select BINARY 'c' <> 'C', BINARY ('c' <> 'C'), (BINARY 'c') <> 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) <> 'C' AS `BINARY 'c' <> 'C'`,cast('c' <> 'C' as char charset binary) AS `BINARY ('c' <> 'C')`,cast('c' as char charset binary) <> 'C' AS `(BINARY 'c') <> 'C'`
+select BINARY 'c' <> 'C', BINARY ('c' <> 'C'), (BINARY 'c') <> 'C' union select * from v1;
+BINARY 'c' <> 'C' BINARY ('c' <> 'C') (BINARY 'c') <> 'C'
+1 0 1
+create or replace view v1 as select BINARY 'c' > 'C', BINARY ('c' > 'C'), (BINARY 'c') > 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) > 'C' AS `BINARY 'c' > 'C'`,cast('c' > 'C' as char charset binary) AS `BINARY ('c' > 'C')`,cast('c' as char charset binary) > 'C' AS `(BINARY 'c') > 'C'`
+select BINARY 'c' > 'C', BINARY ('c' > 'C'), (BINARY 'c') > 'C' union select * from v1;
+BINARY 'c' > 'C' BINARY ('c' > 'C') (BINARY 'c') > 'C'
+1 0 1
+create or replace view v1 as select BINARY 'c' != 'C', BINARY ('c' != 'C'), (BINARY 'c') != 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) <> 'C' AS `BINARY 'c' != 'C'`,cast('c' <> 'C' as char charset binary) AS `BINARY ('c' != 'C')`,cast('c' as char charset binary) <> 'C' AS `(BINARY 'c') != 'C'`
+select BINARY 'c' != 'C', BINARY ('c' != 'C'), (BINARY 'c') != 'C' union select * from v1;
+BINARY 'c' != 'C' BINARY ('c' != 'C') (BINARY 'c') != 'C'
+1 0 1
+create or replace view v1 as select BINARY 'c' LIKE 'C', BINARY ('c' LIKE 'C'), (BINARY 'c') LIKE 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) like 'C' AS `BINARY 'c' LIKE 'C'`,cast('c' like 'C' as char charset binary) AS `BINARY ('c' LIKE 'C')`,cast('c' as char charset binary) like 'C' AS `(BINARY 'c') LIKE 'C'`
+select BINARY 'c' LIKE 'C', BINARY ('c' LIKE 'C'), (BINARY 'c') LIKE 'C' union select * from v1;
+BINARY 'c' LIKE 'C' BINARY ('c' LIKE 'C') (BINARY 'c') LIKE 'C'
+0 1 0
+create or replace view v1 as select BINARY 'c' REGEXP 'C', BINARY ('c' REGEXP 'C'), (BINARY 'c') REGEXP 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) regexp 'C' AS `BINARY 'c' REGEXP 'C'`,cast('c' regexp 'C' as char charset binary) AS `BINARY ('c' REGEXP 'C')`,cast('c' as char charset binary) regexp 'C' AS `(BINARY 'c') REGEXP 'C'`
+select BINARY 'c' REGEXP 'C', BINARY ('c' REGEXP 'C'), (BINARY 'c') REGEXP 'C' union select * from v1;
+BINARY 'c' REGEXP 'C' BINARY ('c' REGEXP 'C') (BINARY 'c') REGEXP 'C'
+0 1 0
+create or replace view v1 as select BINARY 'c' BETWEEN 'A' AND 'D', BINARY ('c' BETWEEN 'A' AND 'D'), (BINARY 'c') BETWEEN 'A' AND 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) between 'A' and 'D' AS `BINARY 'c' BETWEEN 'A' AND 'D'`,cast('c' between 'A' and 'D' as char charset binary) AS `BINARY ('c' BETWEEN 'A' AND 'D')`,cast('c' as char charset binary) between 'A' and 'D' AS `(BINARY 'c') BETWEEN 'A' AND 'D'`
+select BINARY 'c' BETWEEN 'A' AND 'D', BINARY ('c' BETWEEN 'A' AND 'D'), (BINARY 'c') BETWEEN 'A' AND 'D' union select * from v1;
+BINARY 'c' BETWEEN 'A' AND 'D' BINARY ('c' BETWEEN 'A' AND 'D') (BINARY 'c') BETWEEN 'A' AND 'D'
+0 1 0
+create or replace view v1 as select 2 OR 3 IS FALSE, 2 OR (3 IS FALSE), (2 OR 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 is false AS `2 OR 3 IS FALSE`,2 or 3 is false AS `2 OR (3 IS FALSE)`,(2 or 3) is false AS `(2 OR 3) IS FALSE`
+select 2 OR 3 IS FALSE, 2 OR (3 IS FALSE), (2 OR 3) IS FALSE union select * from v1;
+2 OR 3 IS FALSE 2 OR (3 IS FALSE) (2 OR 3) IS FALSE
+1 1 0
+create or replace view v1 as select charset(2 OR 3 COLLATE latin1_bin), charset(2 OR (3 COLLATE latin1_bin)), charset((2 OR 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 or 3 collate latin1_bin) AS `charset(2 OR 3 COLLATE latin1_bin)`,charset(2 or 3 collate latin1_bin) AS `charset(2 OR (3 COLLATE latin1_bin))`,charset((2 or 3) collate latin1_bin) AS `charset((2 OR 3) COLLATE latin1_bin)`
+select charset(2 OR 3 COLLATE latin1_bin), charset(2 OR (3 COLLATE latin1_bin)), charset((2 OR 3) COLLATE latin1_bin) union select * from v1;
+charset(2 OR 3 COLLATE latin1_bin) charset(2 OR (3 COLLATE latin1_bin)) charset((2 OR 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 0 OR 3 IN (3,10), 0 OR (3 IN (3,10)), (0 OR 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 in (3,10) AS `0 OR 3 IN (3,10)`,0 or 3 in (3,10) AS `0 OR (3 IN (3,10))`,(0 or 3) in (3,10) AS `(0 OR 3) IN (3,10)`
+select 0 OR 3 IN (3,10), 0 OR (3 IN (3,10)), (0 OR 3) IN (3,10) union select * from v1;
+0 OR 3 IN (3,10) 0 OR (3 IN (3,10)) (0 OR 3) IN (3,10)
+1 1 0
+create or replace view v1 as select 1 OR 0 XOR 1, 1 OR (0 XOR 1), (1 OR 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 0 xor 1 AS `1 OR 0 XOR 1`,1 or 0 xor 1 AS `1 OR (0 XOR 1)`,(1 or 0) xor 1 AS `(1 OR 0) XOR 1`
+select 1 OR 0 XOR 1, 1 OR (0 XOR 1), (1 OR 0) XOR 1 union select * from v1;
+1 OR 0 XOR 1 1 OR (0 XOR 1) (1 OR 0) XOR 1
+1 1 0
+create or replace view v1 as select 1 OR 1 AND 0, 1 OR (1 AND 0), (1 OR 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 1 and 0 AS `1 OR 1 AND 0`,1 or 1 and 0 AS `1 OR (1 AND 0)`,(1 or 1) and 0 AS `(1 OR 1) AND 0`
+select 1 OR 1 AND 0, 1 OR (1 AND 0), (1 OR 1) AND 0 union select * from v1;
+1 OR 1 AND 0 1 OR (1 AND 0) (1 OR 1) AND 0
+1 1 0
+create or replace view v1 as select 1 OR 1 && 0, 1 OR (1 && 0), (1 OR 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 1 and 0 AS `1 OR 1 && 0`,1 or 1 and 0 AS `1 OR (1 && 0)`,(1 or 1) and 0 AS `(1 OR 1) && 0`
+select 1 OR 1 && 0, 1 OR (1 && 0), (1 OR 1) && 0 union select * from v1;
+1 OR 1 && 0 1 OR (1 && 0) (1 OR 1) && 0
+1 1 0
+create or replace view v1 as select 2 OR 3 = 3, 2 OR (3 = 3), (2 OR 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 = 3 AS `2 OR 3 = 3`,2 or 3 = 3 AS `2 OR (3 = 3)`,(2 or 3) = 3 AS `(2 OR 3) = 3`
+select 2 OR 3 = 3, 2 OR (3 = 3), (2 OR 3) = 3 union select * from v1;
+2 OR 3 = 3 2 OR (3 = 3) (2 OR 3) = 3
+1 1 0
+create or replace view v1 as select 2 OR 3 <=> 3, 2 OR (3 <=> 3), (2 OR 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 <=> 3 AS `2 OR 3 <=> 3`,2 or 3 <=> 3 AS `2 OR (3 <=> 3)`,(2 or 3) <=> 3 AS `(2 OR 3) <=> 3`
+select 2 OR 3 <=> 3, 2 OR (3 <=> 3), (2 OR 3) <=> 3 union select * from v1;
+2 OR 3 <=> 3 2 OR (3 <=> 3) (2 OR 3) <=> 3
+1 1 0
+create or replace view v1 as select 2 OR 3 >= 3, 2 OR (3 >= 3), (2 OR 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 >= 3 AS `2 OR 3 >= 3`,2 or 3 >= 3 AS `2 OR (3 >= 3)`,(2 or 3) >= 3 AS `(2 OR 3) >= 3`
+select 2 OR 3 >= 3, 2 OR (3 >= 3), (2 OR 3) >= 3 union select * from v1;
+2 OR 3 >= 3 2 OR (3 >= 3) (2 OR 3) >= 3
+1 1 0
+create or replace view v1 as select 2 OR 3 <= 0, 2 OR (3 <= 0), (2 OR 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 <= 0 AS `2 OR 3 <= 0`,2 or 3 <= 0 AS `2 OR (3 <= 0)`,(2 or 3) <= 0 AS `(2 OR 3) <= 0`
+select 2 OR 3 <= 0, 2 OR (3 <= 0), (2 OR 3) <= 0 union select * from v1;
+2 OR 3 <= 0 2 OR (3 <= 0) (2 OR 3) <= 0
+1 1 0
+create or replace view v1 as select 2 OR 3 < 0, 2 OR (3 < 0), (2 OR 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 < 0 AS `2 OR 3 < 0`,2 or 3 < 0 AS `2 OR (3 < 0)`,(2 or 3) < 0 AS `(2 OR 3) < 0`
+select 2 OR 3 < 0, 2 OR (3 < 0), (2 OR 3) < 0 union select * from v1;
+2 OR 3 < 0 2 OR (3 < 0) (2 OR 3) < 0
+1 1 0
+create or replace view v1 as select 0 OR 3 <> 3, 0 OR (3 <> 3), (0 OR 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 <> 3 AS `0 OR 3 <> 3`,0 or 3 <> 3 AS `0 OR (3 <> 3)`,(0 or 3) <> 3 AS `(0 OR 3) <> 3`
+select 0 OR 3 <> 3, 0 OR (3 <> 3), (0 OR 3) <> 3 union select * from v1;
+0 OR 3 <> 3 0 OR (3 <> 3) (0 OR 3) <> 3
+0 0 1
+create or replace view v1 as select 2 OR 3 > 3, 2 OR (3 > 3), (2 OR 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 > 3 AS `2 OR 3 > 3`,2 or 3 > 3 AS `2 OR (3 > 3)`,(2 or 3) > 3 AS `(2 OR 3) > 3`
+select 2 OR 3 > 3, 2 OR (3 > 3), (2 OR 3) > 3 union select * from v1;
+2 OR 3 > 3 2 OR (3 > 3) (2 OR 3) > 3
+1 1 0
+create or replace view v1 as select 0 OR 3 != 3, 0 OR (3 != 3), (0 OR 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 <> 3 AS `0 OR 3 != 3`,0 or 3 <> 3 AS `0 OR (3 != 3)`,(0 or 3) <> 3 AS `(0 OR 3) != 3`
+select 0 OR 3 != 3, 0 OR (3 != 3), (0 OR 3) != 3 union select * from v1;
+0 OR 3 != 3 0 OR (3 != 3) (0 OR 3) != 3
+0 0 1
+create or replace view v1 as select 2 OR 3 LIKE 3, 2 OR (3 LIKE 3), (2 OR 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 like 3 AS `2 OR 3 LIKE 3`,2 or 3 like 3 AS `2 OR (3 LIKE 3)`,(2 or 3) like 3 AS `(2 OR 3) LIKE 3`
+select 2 OR 3 LIKE 3, 2 OR (3 LIKE 3), (2 OR 3) LIKE 3 union select * from v1;
+2 OR 3 LIKE 3 2 OR (3 LIKE 3) (2 OR 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 OR 3 REGEXP 3, 2 OR (3 REGEXP 3), (2 OR 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 regexp 3 AS `2 OR 3 REGEXP 3`,2 or 3 regexp 3 AS `2 OR (3 REGEXP 3)`,(2 or 3) regexp 3 AS `(2 OR 3) REGEXP 3`
+select 2 OR 3 REGEXP 3, 2 OR (3 REGEXP 3), (2 OR 3) REGEXP 3 union select * from v1;
+2 OR 3 REGEXP 3 2 OR (3 REGEXP 3) (2 OR 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 OR 3 | 3, 2 OR (3 | 3), (2 OR 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 | 3 AS `2 OR 3 | 3`,2 or 3 | 3 AS `2 OR (3 | 3)`,(2 or 3) | 3 AS `(2 OR 3) | 3`
+select 2 OR 3 | 3, 2 OR (3 | 3), (2 OR 3) | 3 union select * from v1;
+2 OR 3 | 3 2 OR (3 | 3) (2 OR 3) | 3
+1 1 3
+create or replace view v1 as select 0 OR 2 & 2, 0 OR (2 & 2), (0 OR 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 2 & 2 AS `0 OR 2 & 2`,0 or 2 & 2 AS `0 OR (2 & 2)`,(0 or 2) & 2 AS `(0 OR 2) & 2`
+select 0 OR 2 & 2, 0 OR (2 & 2), (0 OR 2) & 2 union select * from v1;
+0 OR 2 & 2 0 OR (2 & 2) (0 OR 2) & 2
+1 1 0
+create or replace view v1 as select 2 OR 3 << 3, 2 OR (3 << 3), (2 OR 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 << 3 AS `2 OR 3 << 3`,2 or 3 << 3 AS `2 OR (3 << 3)`,(2 or 3) << 3 AS `(2 OR 3) << 3`
+select 2 OR 3 << 3, 2 OR (3 << 3), (2 OR 3) << 3 union select * from v1;
+2 OR 3 << 3 2 OR (3 << 3) (2 OR 3) << 3
+1 1 8
+create or replace view v1 as select 2 OR 3 >> 3, 2 OR (3 >> 3), (2 OR 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 >> 3 AS `2 OR 3 >> 3`,2 or 3 >> 3 AS `2 OR (3 >> 3)`,(2 or 3) >> 3 AS `(2 OR 3) >> 3`
+select 2 OR 3 >> 3, 2 OR (3 >> 3), (2 OR 3) >> 3 union select * from v1;
+2 OR 3 >> 3 2 OR (3 >> 3) (2 OR 3) >> 3
+1 1 0
+create or replace view v1 as select 2 OR '2000-01-01' +INTERVAL 1 DAY, 2 OR ('2000-01-01' +INTERVAL 1 DAY), (2 OR '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or '2000-01-01' + interval 1 day AS `2 OR '2000-01-01' +INTERVAL 1 DAY`,2 or '2000-01-01' + interval 1 day AS `2 OR ('2000-01-01' +INTERVAL 1 DAY)`,(2 or '2000-01-01') + interval 1 day AS `(2 OR '2000-01-01') +INTERVAL 1 DAY`
+select 2 OR '2000-01-01' +INTERVAL 1 DAY, 2 OR ('2000-01-01' +INTERVAL 1 DAY), (2 OR '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 OR '2000-01-01' +INTERVAL 1 DAY 2 OR ('2000-01-01' +INTERVAL 1 DAY) (2 OR '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 OR 3 + 3, 2 OR (3 + 3), (2 OR 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 + 3 AS `2 OR 3 + 3`,2 or 3 + 3 AS `2 OR (3 + 3)`,(2 or 3) + 3 AS `(2 OR 3) + 3`
+select 2 OR 3 + 3, 2 OR (3 + 3), (2 OR 3) + 3 union select * from v1;
+2 OR 3 + 3 2 OR (3 + 3) (2 OR 3) + 3
+1 1 4
+create or replace view v1 as select 2 OR 3 - 3, 2 OR (3 - 3), (2 OR 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 - 3 AS `2 OR 3 - 3`,2 or 3 - 3 AS `2 OR (3 - 3)`,(2 or 3) - 3 AS `(2 OR 3) - 3`
+select 2 OR 3 - 3, 2 OR (3 - 3), (2 OR 3) - 3 union select * from v1;
+2 OR 3 - 3 2 OR (3 - 3) (2 OR 3) - 3
+1 1 -2
+create or replace view v1 as select 2 OR 3 * 3, 2 OR (3 * 3), (2 OR 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 * 3 AS `2 OR 3 * 3`,2 or 3 * 3 AS `2 OR (3 * 3)`,(2 or 3) * 3 AS `(2 OR 3) * 3`
+select 2 OR 3 * 3, 2 OR (3 * 3), (2 OR 3) * 3 union select * from v1;
+2 OR 3 * 3 2 OR (3 * 3) (2 OR 3) * 3
+1 1 3
+create or replace view v1 as select 2 OR 3 / 3, 2 OR (3 / 3), (2 OR 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 / 3 AS `2 OR 3 / 3`,2 or 3 / 3 AS `2 OR (3 / 3)`,(2 or 3) / 3 AS `(2 OR 3) / 3`
+select 2 OR 3 / 3, 2 OR (3 / 3), (2 OR 3) / 3 union select * from v1;
+2 OR 3 / 3 2 OR (3 / 3) (2 OR 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 OR 3 DIV 3, 2 OR (3 DIV 3), (2 OR 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 DIV 3 AS `2 OR 3 DIV 3`,2 or 3 DIV 3 AS `2 OR (3 DIV 3)`,(2 or 3) DIV 3 AS `(2 OR 3) DIV 3`
+select 2 OR 3 DIV 3, 2 OR (3 DIV 3), (2 OR 3) DIV 3 union select * from v1;
+2 OR 3 DIV 3 2 OR (3 DIV 3) (2 OR 3) DIV 3
+1 1 0
+create or replace view v1 as select 0 OR 3 MOD 3, 0 OR (3 MOD 3), (0 OR 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 MOD 3 AS `0 OR 3 MOD 3`,0 or 3 MOD 3 AS `0 OR (3 MOD 3)`,(0 or 3) MOD 3 AS `(0 OR 3) MOD 3`
+select 0 OR 3 MOD 3, 0 OR (3 MOD 3), (0 OR 3) MOD 3 union select * from v1;
+0 OR 3 MOD 3 0 OR (3 MOD 3) (0 OR 3) MOD 3
+0 0 1
+create or replace view v1 as select 0 OR 3 % 3, 0 OR (3 % 3), (0 OR 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 MOD 3 AS `0 OR 3 % 3`,0 or 3 MOD 3 AS `0 OR (3 % 3)`,(0 or 3) MOD 3 AS `(0 OR 3) % 3`
+select 0 OR 3 % 3, 0 OR (3 % 3), (0 OR 3) % 3 union select * from v1;
+0 OR 3 % 3 0 OR (3 % 3) (0 OR 3) % 3
+0 0 1
+create or replace view v1 as select 2 OR 3 ^ 3, 2 OR (3 ^ 3), (2 OR 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 ^ 3 AS `2 OR 3 ^ 3`,2 or 3 ^ 3 AS `2 OR (3 ^ 3)`,(2 or 3) ^ 3 AS `(2 OR 3) ^ 3`
+select 2 OR 3 ^ 3, 2 OR (3 ^ 3), (2 OR 3) ^ 3 union select * from v1;
+2 OR 3 ^ 3 2 OR (3 ^ 3) (2 OR 3) ^ 3
+1 1 2
+create or replace view v1 as select 2 OR 3 BETWEEN 2 AND 3, 2 OR (3 BETWEEN 2 AND 3), (2 OR 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 between 2 and 3 AS `2 OR 3 BETWEEN 2 AND 3`,2 or 3 between 2 and 3 AS `2 OR (3 BETWEEN 2 AND 3)`,(2 or 3) between 2 and 3 AS `(2 OR 3) BETWEEN 2 AND 3`
+select 2 OR 3 BETWEEN 2 AND 3, 2 OR (3 BETWEEN 2 AND 3), (2 OR 3) BETWEEN 2 AND 3 union select * from v1;
+2 OR 3 BETWEEN 2 AND 3 2 OR (3 BETWEEN 2 AND 3) (2 OR 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 is false AS `2 || 3 IS FALSE`,2 or 3 is false AS `2 || (3 IS FALSE)`,(2 or 3) is false AS `(2 || 3) IS FALSE`
+select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE union select * from v1;
+2 || 3 IS FALSE 2 || (3 IS FALSE) (2 || 3) IS FALSE
+1 1 0
+create or replace view v1 as select charset(2 || 3 COLLATE latin1_bin), charset(2 || (3 COLLATE latin1_bin)), charset((2 || 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 or 3 collate latin1_bin) AS `charset(2 || 3 COLLATE latin1_bin)`,charset(2 or 3 collate latin1_bin) AS `charset(2 || (3 COLLATE latin1_bin))`,charset((2 or 3) collate latin1_bin) AS `charset((2 || 3) COLLATE latin1_bin)`
+select charset(2 || 3 COLLATE latin1_bin), charset(2 || (3 COLLATE latin1_bin)), charset((2 || 3) COLLATE latin1_bin) union select * from v1;
+charset(2 || 3 COLLATE latin1_bin) charset(2 || (3 COLLATE latin1_bin)) charset((2 || 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 in (3,10) AS `0 || 3 IN (3,10)`,0 or 3 in (3,10) AS `0 || (3 IN (3,10))`,(0 or 3) in (3,10) AS `(0 || 3) IN (3,10)`
+select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10) union select * from v1;
+0 || 3 IN (3,10) 0 || (3 IN (3,10)) (0 || 3) IN (3,10)
+1 1 0
+create or replace view v1 as select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 0 xor 1 AS `1 || 0 XOR 1`,1 or 0 xor 1 AS `1 || (0 XOR 1)`,(1 or 0) xor 1 AS `(1 || 0) XOR 1`
+select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1 union select * from v1;
+1 || 0 XOR 1 1 || (0 XOR 1) (1 || 0) XOR 1
+1 1 0
+create or replace view v1 as select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 1 and 0 AS `1 || 1 AND 0`,1 or 1 and 0 AS `1 || (1 AND 0)`,(1 or 1) and 0 AS `(1 || 1) AND 0`
+select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0 union select * from v1;
+1 || 1 AND 0 1 || (1 AND 0) (1 || 1) AND 0
+1 1 0
+create or replace view v1 as select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 or 1 and 0 AS `1 || 1 && 0`,1 or 1 and 0 AS `1 || (1 && 0)`,(1 or 1) and 0 AS `(1 || 1) && 0`
+select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0 union select * from v1;
+1 || 1 && 0 1 || (1 && 0) (1 || 1) && 0
+1 1 0
+create or replace view v1 as select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 = 3 AS `2 || 3 = 3`,2 or 3 = 3 AS `2 || (3 = 3)`,(2 or 3) = 3 AS `(2 || 3) = 3`
+select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3 union select * from v1;
+2 || 3 = 3 2 || (3 = 3) (2 || 3) = 3
+1 1 0
+create or replace view v1 as select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 <=> 3 AS `2 || 3 <=> 3`,2 or 3 <=> 3 AS `2 || (3 <=> 3)`,(2 or 3) <=> 3 AS `(2 || 3) <=> 3`
+select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3 union select * from v1;
+2 || 3 <=> 3 2 || (3 <=> 3) (2 || 3) <=> 3
+1 1 0
+create or replace view v1 as select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 >= 3 AS `2 || 3 >= 3`,2 or 3 >= 3 AS `2 || (3 >= 3)`,(2 or 3) >= 3 AS `(2 || 3) >= 3`
+select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3 union select * from v1;
+2 || 3 >= 3 2 || (3 >= 3) (2 || 3) >= 3
+1 1 0
+create or replace view v1 as select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 <= 0 AS `2 || 3 <= 0`,2 or 3 <= 0 AS `2 || (3 <= 0)`,(2 or 3) <= 0 AS `(2 || 3) <= 0`
+select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0 union select * from v1;
+2 || 3 <= 0 2 || (3 <= 0) (2 || 3) <= 0
+1 1 0
+create or replace view v1 as select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 < 0 AS `2 || 3 < 0`,2 or 3 < 0 AS `2 || (3 < 0)`,(2 or 3) < 0 AS `(2 || 3) < 0`
+select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0 union select * from v1;
+2 || 3 < 0 2 || (3 < 0) (2 || 3) < 0
+1 1 0
+create or replace view v1 as select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 <> 3 AS `0 || 3 <> 3`,0 or 3 <> 3 AS `0 || (3 <> 3)`,(0 or 3) <> 3 AS `(0 || 3) <> 3`
+select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3 union select * from v1;
+0 || 3 <> 3 0 || (3 <> 3) (0 || 3) <> 3
+0 0 1
+create or replace view v1 as select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 > 3 AS `2 || 3 > 3`,2 or 3 > 3 AS `2 || (3 > 3)`,(2 or 3) > 3 AS `(2 || 3) > 3`
+select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3 union select * from v1;
+2 || 3 > 3 2 || (3 > 3) (2 || 3) > 3
+1 1 0
+create or replace view v1 as select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 <> 3 AS `0 || 3 != 3`,0 or 3 <> 3 AS `0 || (3 != 3)`,(0 or 3) <> 3 AS `(0 || 3) != 3`
+select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3 union select * from v1;
+0 || 3 != 3 0 || (3 != 3) (0 || 3) != 3
+0 0 1
+create or replace view v1 as select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 like 3 AS `2 || 3 LIKE 3`,2 or 3 like 3 AS `2 || (3 LIKE 3)`,(2 or 3) like 3 AS `(2 || 3) LIKE 3`
+select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3 union select * from v1;
+2 || 3 LIKE 3 2 || (3 LIKE 3) (2 || 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 regexp 3 AS `2 || 3 REGEXP 3`,2 or 3 regexp 3 AS `2 || (3 REGEXP 3)`,(2 or 3) regexp 3 AS `(2 || 3) REGEXP 3`
+select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3 union select * from v1;
+2 || 3 REGEXP 3 2 || (3 REGEXP 3) (2 || 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 || 3 | 3, 2 || (3 | 3), (2 || 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 | 3 AS `2 || 3 | 3`,2 or 3 | 3 AS `2 || (3 | 3)`,(2 or 3) | 3 AS `(2 || 3) | 3`
+select 2 || 3 | 3, 2 || (3 | 3), (2 || 3) | 3 union select * from v1;
+2 || 3 | 3 2 || (3 | 3) (2 || 3) | 3
+1 1 3
+create or replace view v1 as select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 2 & 2 AS `0 || 2 & 2`,0 or 2 & 2 AS `0 || (2 & 2)`,(0 or 2) & 2 AS `(0 || 2) & 2`
+select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2 union select * from v1;
+0 || 2 & 2 0 || (2 & 2) (0 || 2) & 2
+1 1 0
+create or replace view v1 as select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 << 3 AS `2 || 3 << 3`,2 or 3 << 3 AS `2 || (3 << 3)`,(2 or 3) << 3 AS `(2 || 3) << 3`
+select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3 union select * from v1;
+2 || 3 << 3 2 || (3 << 3) (2 || 3) << 3
+1 1 8
+create or replace view v1 as select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 >> 3 AS `2 || 3 >> 3`,2 or 3 >> 3 AS `2 || (3 >> 3)`,(2 or 3) >> 3 AS `(2 || 3) >> 3`
+select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3 union select * from v1;
+2 || 3 >> 3 2 || (3 >> 3) (2 || 3) >> 3
+1 1 0
+create or replace view v1 as select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or '2000-01-01' + interval 1 day AS `2 || '2000-01-01' +INTERVAL 1 DAY`,2 or '2000-01-01' + interval 1 day AS `2 || ('2000-01-01' +INTERVAL 1 DAY)`,(2 or '2000-01-01') + interval 1 day AS `(2 || '2000-01-01') +INTERVAL 1 DAY`
+select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 || '2000-01-01' +INTERVAL 1 DAY 2 || ('2000-01-01' +INTERVAL 1 DAY) (2 || '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 || 3 + 3, 2 || (3 + 3), (2 || 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 + 3 AS `2 || 3 + 3`,2 or 3 + 3 AS `2 || (3 + 3)`,(2 or 3) + 3 AS `(2 || 3) + 3`
+select 2 || 3 + 3, 2 || (3 + 3), (2 || 3) + 3 union select * from v1;
+2 || 3 + 3 2 || (3 + 3) (2 || 3) + 3
+1 1 4
+create or replace view v1 as select 2 || 3 - 3, 2 || (3 - 3), (2 || 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 - 3 AS `2 || 3 - 3`,2 or 3 - 3 AS `2 || (3 - 3)`,(2 or 3) - 3 AS `(2 || 3) - 3`
+select 2 || 3 - 3, 2 || (3 - 3), (2 || 3) - 3 union select * from v1;
+2 || 3 - 3 2 || (3 - 3) (2 || 3) - 3
+1 1 -2
+create or replace view v1 as select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 * 3 AS `2 || 3 * 3`,2 or 3 * 3 AS `2 || (3 * 3)`,(2 or 3) * 3 AS `(2 || 3) * 3`
+select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3 union select * from v1;
+2 || 3 * 3 2 || (3 * 3) (2 || 3) * 3
+1 1 3
+create or replace view v1 as select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 / 3 AS `2 || 3 / 3`,2 or 3 / 3 AS `2 || (3 / 3)`,(2 or 3) / 3 AS `(2 || 3) / 3`
+select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3 union select * from v1;
+2 || 3 / 3 2 || (3 / 3) (2 || 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 DIV 3 AS `2 || 3 DIV 3`,2 or 3 DIV 3 AS `2 || (3 DIV 3)`,(2 or 3) DIV 3 AS `(2 || 3) DIV 3`
+select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3 union select * from v1;
+2 || 3 DIV 3 2 || (3 DIV 3) (2 || 3) DIV 3
+1 1 0
+create or replace view v1 as select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 MOD 3 AS `0 || 3 MOD 3`,0 or 3 MOD 3 AS `0 || (3 MOD 3)`,(0 or 3) MOD 3 AS `(0 || 3) MOD 3`
+select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3 union select * from v1;
+0 || 3 MOD 3 0 || (3 MOD 3) (0 || 3) MOD 3
+0 0 1
+create or replace view v1 as select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 MOD 3 AS `0 || 3 % 3`,0 or 3 MOD 3 AS `0 || (3 % 3)`,(0 or 3) MOD 3 AS `(0 || 3) % 3`
+select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3 union select * from v1;
+0 || 3 % 3 0 || (3 % 3) (0 || 3) % 3
+0 0 1
+create or replace view v1 as select 2 || 3 ^ 3, 2 || (3 ^ 3), (2 || 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 ^ 3 AS `2 || 3 ^ 3`,2 or 3 ^ 3 AS `2 || (3 ^ 3)`,(2 or 3) ^ 3 AS `(2 || 3) ^ 3`
+select 2 || 3 ^ 3, 2 || (3 ^ 3), (2 || 3) ^ 3 union select * from v1;
+2 || 3 ^ 3 2 || (3 ^ 3) (2 || 3) ^ 3
+1 1 2
+create or replace view v1 as select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or 3 between 2 and 3 AS `2 || 3 BETWEEN 2 AND 3`,2 or 3 between 2 and 3 AS `2 || (3 BETWEEN 2 AND 3)`,(2 or 3) between 2 and 3 AS `(2 || 3) BETWEEN 2 AND 3`
+select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3 union select * from v1;
+2 || 3 BETWEEN 2 AND 3 2 || (3 BETWEEN 2 AND 3) (2 || 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select charset(2 XOR 3 COLLATE latin1_bin), charset(2 XOR (3 COLLATE latin1_bin)), charset((2 XOR 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 xor 3 collate latin1_bin) AS `charset(2 XOR 3 COLLATE latin1_bin)`,charset(2 xor 3 collate latin1_bin) AS `charset(2 XOR (3 COLLATE latin1_bin))`,charset((2 xor 3) collate latin1_bin) AS `charset((2 XOR 3) COLLATE latin1_bin)`
+select charset(2 XOR 3 COLLATE latin1_bin), charset(2 XOR (3 COLLATE latin1_bin)), charset((2 XOR 3) COLLATE latin1_bin) union select * from v1;
+charset(2 XOR 3 COLLATE latin1_bin) charset(2 XOR (3 COLLATE latin1_bin)) charset((2 XOR 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 XOR 3 IN (4,5), 2 XOR (3 IN (4,5)), (2 XOR 3) IN (4,5);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 in (4,5) AS `2 XOR 3 IN (4,5)`,2 xor 3 in (4,5) AS `2 XOR (3 IN (4,5))`,(2 xor 3) in (4,5) AS `(2 XOR 3) IN (4,5)`
+select 2 XOR 3 IN (4,5), 2 XOR (3 IN (4,5)), (2 XOR 3) IN (4,5) union select * from v1;
+2 XOR 3 IN (4,5) 2 XOR (3 IN (4,5)) (2 XOR 3) IN (4,5)
+1 1 0
+create or replace view v1 as select 2 XOR 3 OR 3, 2 XOR (3 OR 3), (2 XOR 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 or 3 AS `2 XOR 3 OR 3`,2 xor (3 or 3) AS `2 XOR (3 OR 3)`,2 xor 3 or 3 AS `(2 XOR 3) OR 3`
+select 2 XOR 3 OR 3, 2 XOR (3 OR 3), (2 XOR 3) OR 3 union select * from v1;
+2 XOR 3 OR 3 2 XOR (3 OR 3) (2 XOR 3) OR 3
+1 0 1
+create or replace view v1 as select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 or 3 AS `2 XOR 3 || 3`,2 xor (3 or 3) AS `2 XOR (3 || 3)`,2 xor 3 or 3 AS `(2 XOR 3) || 3`
+select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3 union select * from v1;
+2 XOR 3 || 3 2 XOR (3 || 3) (2 XOR 3) || 3
+1 0 1
+create or replace view v1 as select 2 XOR 0 AND 0, 2 XOR (0 AND 0), (2 XOR 0) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 0 and 0 AS `2 XOR 0 AND 0`,2 xor 0 and 0 AS `2 XOR (0 AND 0)`,(2 xor 0) and 0 AS `(2 XOR 0) AND 0`
+select 2 XOR 0 AND 0, 2 XOR (0 AND 0), (2 XOR 0) AND 0 union select * from v1;
+2 XOR 0 AND 0 2 XOR (0 AND 0) (2 XOR 0) AND 0
+1 1 0
+create or replace view v1 as select 2 XOR 0 && 0, 2 XOR (0 && 0), (2 XOR 0) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 0 and 0 AS `2 XOR 0 && 0`,2 xor 0 and 0 AS `2 XOR (0 && 0)`,(2 xor 0) and 0 AS `(2 XOR 0) && 0`
+select 2 XOR 0 && 0, 2 XOR (0 && 0), (2 XOR 0) && 0 union select * from v1;
+2 XOR 0 && 0 2 XOR (0 && 0) (2 XOR 0) && 0
+1 1 0
+create or replace view v1 as select 2 XOR 2 = 3, 2 XOR (2 = 3), (2 XOR 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 2 = 3 AS `2 XOR 2 = 3`,2 xor 2 = 3 AS `2 XOR (2 = 3)`,(2 xor 2) = 3 AS `(2 XOR 2) = 3`
+select 2 XOR 2 = 3, 2 XOR (2 = 3), (2 XOR 2) = 3 union select * from v1;
+2 XOR 2 = 3 2 XOR (2 = 3) (2 XOR 2) = 3
+1 1 0
+create or replace view v1 as select NULL XOR 3 <=> 3, NULL XOR (3 <=> 3), (NULL XOR 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select NULL xor 3 <=> 3 AS `NULL XOR 3 <=> 3`,NULL xor 3 <=> 3 AS `NULL XOR (3 <=> 3)`,(NULL xor 3) <=> 3 AS `(NULL XOR 3) <=> 3`
+select NULL XOR 3 <=> 3, NULL XOR (3 <=> 3), (NULL XOR 3) <=> 3 union select * from v1;
+NULL XOR 3 <=> 3 NULL XOR (3 <=> 3) (NULL XOR 3) <=> 3
+NULL NULL 0
+create or replace view v1 as select 2 XOR 1 >= 3, 2 XOR (1 >= 3), (2 XOR 1) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 1 >= 3 AS `2 XOR 1 >= 3`,2 xor 1 >= 3 AS `2 XOR (1 >= 3)`,(2 xor 1) >= 3 AS `(2 XOR 1) >= 3`
+select 2 XOR 1 >= 3, 2 XOR (1 >= 3), (2 XOR 1) >= 3 union select * from v1;
+2 XOR 1 >= 3 2 XOR (1 >= 3) (2 XOR 1) >= 3
+1 1 0
+create or replace view v1 as select 2 XOR 3 <= 3, 2 XOR (3 <= 3), (2 XOR 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 <= 3 AS `2 XOR 3 <= 3`,2 xor 3 <= 3 AS `2 XOR (3 <= 3)`,(2 xor 3) <= 3 AS `(2 XOR 3) <= 3`
+select 2 XOR 3 <= 3, 2 XOR (3 <= 3), (2 XOR 3) <= 3 union select * from v1;
+2 XOR 3 <= 3 2 XOR (3 <= 3) (2 XOR 3) <= 3
+0 0 1
+create or replace view v1 as select 2 XOR 1 < 3, 2 XOR (1 < 3), (2 XOR 1) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 1 < 3 AS `2 XOR 1 < 3`,2 xor 1 < 3 AS `2 XOR (1 < 3)`,(2 xor 1) < 3 AS `(2 XOR 1) < 3`
+select 2 XOR 1 < 3, 2 XOR (1 < 3), (2 XOR 1) < 3 union select * from v1;
+2 XOR 1 < 3 2 XOR (1 < 3) (2 XOR 1) < 3
+0 0 1
+create or replace view v1 as select 2 XOR 2 <> 3, 2 XOR (2 <> 3), (2 XOR 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 2 <> 3 AS `2 XOR 2 <> 3`,2 xor 2 <> 3 AS `2 XOR (2 <> 3)`,(2 xor 2) <> 3 AS `(2 XOR 2) <> 3`
+select 2 XOR 2 <> 3, 2 XOR (2 <> 3), (2 XOR 2) <> 3 union select * from v1;
+2 XOR 2 <> 3 2 XOR (2 <> 3) (2 XOR 2) <> 3
+0 0 1
+create or replace view v1 as select 2 XOR 3 > 3, 2 XOR (3 > 3), (2 XOR 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 > 3 AS `2 XOR 3 > 3`,2 xor 3 > 3 AS `2 XOR (3 > 3)`,(2 xor 3) > 3 AS `(2 XOR 3) > 3`
+select 2 XOR 3 > 3, 2 XOR (3 > 3), (2 XOR 3) > 3 union select * from v1;
+2 XOR 3 > 3 2 XOR (3 > 3) (2 XOR 3) > 3
+1 1 0
+create or replace view v1 as select 2 XOR 2 != 3, 2 XOR (2 != 3), (2 XOR 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 2 <> 3 AS `2 XOR 2 != 3`,2 xor 2 <> 3 AS `2 XOR (2 != 3)`,(2 xor 2) <> 3 AS `(2 XOR 2) != 3`
+select 2 XOR 2 != 3, 2 XOR (2 != 3), (2 XOR 2) != 3 union select * from v1;
+2 XOR 2 != 3 2 XOR (2 != 3) (2 XOR 2) != 3
+0 0 1
+create or replace view v1 as select 2 XOR 1 LIKE 3, 2 XOR (1 LIKE 3), (2 XOR 1) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 1 like 3 AS `2 XOR 1 LIKE 3`,2 xor 1 like 3 AS `2 XOR (1 LIKE 3)`,(2 xor 1) like 3 AS `(2 XOR 1) LIKE 3`
+select 2 XOR 1 LIKE 3, 2 XOR (1 LIKE 3), (2 XOR 1) LIKE 3 union select * from v1;
+2 XOR 1 LIKE 3 2 XOR (1 LIKE 3) (2 XOR 1) LIKE 3
+1 1 0
+create or replace view v1 as select 2 XOR 1 REGEXP 3, 2 XOR (1 REGEXP 3), (2 XOR 1) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 1 regexp 3 AS `2 XOR 1 REGEXP 3`,2 xor 1 regexp 3 AS `2 XOR (1 REGEXP 3)`,(2 xor 1) regexp 3 AS `(2 XOR 1) REGEXP 3`
+select 2 XOR 1 REGEXP 3, 2 XOR (1 REGEXP 3), (2 XOR 1) REGEXP 3 union select * from v1;
+2 XOR 1 REGEXP 3 2 XOR (1 REGEXP 3) (2 XOR 1) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 XOR 3 | 3, 2 XOR (3 | 3), (2 XOR 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 | 3 AS `2 XOR 3 | 3`,2 xor 3 | 3 AS `2 XOR (3 | 3)`,(2 xor 3) | 3 AS `(2 XOR 3) | 3`
+select 2 XOR 3 | 3, 2 XOR (3 | 3), (2 XOR 3) | 3 union select * from v1;
+2 XOR 3 | 3 2 XOR (3 | 3) (2 XOR 3) | 3
+0 0 3
+create or replace view v1 as select 2 XOR 0 & 0, 2 XOR (0 & 0), (2 XOR 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 0 & 0 AS `2 XOR 0 & 0`,2 xor 0 & 0 AS `2 XOR (0 & 0)`,(2 xor 0) & 0 AS `(2 XOR 0) & 0`
+select 2 XOR 0 & 0, 2 XOR (0 & 0), (2 XOR 0) & 0 union select * from v1;
+2 XOR 0 & 0 2 XOR (0 & 0) (2 XOR 0) & 0
+1 1 0
+create or replace view v1 as select 0 XOR 3 << 3, 0 XOR (3 << 3), (0 XOR 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 xor 3 << 3 AS `0 XOR 3 << 3`,0 xor 3 << 3 AS `0 XOR (3 << 3)`,(0 xor 3) << 3 AS `(0 XOR 3) << 3`
+select 0 XOR 3 << 3, 0 XOR (3 << 3), (0 XOR 3) << 3 union select * from v1;
+0 XOR 3 << 3 0 XOR (3 << 3) (0 XOR 3) << 3
+1 1 8
+create or replace view v1 as select 2 XOR 3 >> 3, 2 XOR (3 >> 3), (2 XOR 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 >> 3 AS `2 XOR 3 >> 3`,2 xor 3 >> 3 AS `2 XOR (3 >> 3)`,(2 xor 3) >> 3 AS `(2 XOR 3) >> 3`
+select 2 XOR 3 >> 3, 2 XOR (3 >> 3), (2 XOR 3) >> 3 union select * from v1;
+2 XOR 3 >> 3 2 XOR (3 >> 3) (2 XOR 3) >> 3
+1 1 0
+create or replace view v1 as select 2 XOR '2000-01-01' +INTERVAL 1 DAY, 2 XOR ('2000-01-01' +INTERVAL 1 DAY), (2 XOR '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor '2000-01-01' + interval 1 day AS `2 XOR '2000-01-01' +INTERVAL 1 DAY`,2 xor '2000-01-01' + interval 1 day AS `2 XOR ('2000-01-01' +INTERVAL 1 DAY)`,(2 xor '2000-01-01') + interval 1 day AS `(2 XOR '2000-01-01') +INTERVAL 1 DAY`
+select 2 XOR '2000-01-01' +INTERVAL 1 DAY, 2 XOR ('2000-01-01' +INTERVAL 1 DAY), (2 XOR '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 XOR '2000-01-01' +INTERVAL 1 DAY 2 XOR ('2000-01-01' +INTERVAL 1 DAY) (2 XOR '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 XOR 3 + 3, 2 XOR (3 + 3), (2 XOR 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 + 3 AS `2 XOR 3 + 3`,2 xor 3 + 3 AS `2 XOR (3 + 3)`,(2 xor 3) + 3 AS `(2 XOR 3) + 3`
+select 2 XOR 3 + 3, 2 XOR (3 + 3), (2 XOR 3) + 3 union select * from v1;
+2 XOR 3 + 3 2 XOR (3 + 3) (2 XOR 3) + 3
+0 0 3
+create or replace view v1 as select 2 XOR 3 - 3, 2 XOR (3 - 3), (2 XOR 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 - 3 AS `2 XOR 3 - 3`,2 xor 3 - 3 AS `2 XOR (3 - 3)`,(2 xor 3) - 3 AS `(2 XOR 3) - 3`
+select 2 XOR 3 - 3, 2 XOR (3 - 3), (2 XOR 3) - 3 union select * from v1;
+2 XOR 3 - 3 2 XOR (3 - 3) (2 XOR 3) - 3
+1 1 -3
+create or replace view v1 as select 0 XOR 3 * 3, 0 XOR (3 * 3), (0 XOR 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 xor 3 * 3 AS `0 XOR 3 * 3`,0 xor 3 * 3 AS `0 XOR (3 * 3)`,(0 xor 3) * 3 AS `(0 XOR 3) * 3`
+select 0 XOR 3 * 3, 0 XOR (3 * 3), (0 XOR 3) * 3 union select * from v1;
+0 XOR 3 * 3 0 XOR (3 * 3) (0 XOR 3) * 3
+1 1 3
+create or replace view v1 as select 0 XOR 3 / 3, 0 XOR (3 / 3), (0 XOR 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 xor 3 / 3 AS `0 XOR 3 / 3`,0 xor 3 / 3 AS `0 XOR (3 / 3)`,(0 xor 3) / 3 AS `(0 XOR 3) / 3`
+select 0 XOR 3 / 3, 0 XOR (3 / 3), (0 XOR 3) / 3 union select * from v1;
+0 XOR 3 / 3 0 XOR (3 / 3) (0 XOR 3) / 3
+1 1 0.3333
+create or replace view v1 as select 0 XOR 3 DIV 3, 0 XOR (3 DIV 3), (0 XOR 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 xor 3 DIV 3 AS `0 XOR 3 DIV 3`,0 xor 3 DIV 3 AS `0 XOR (3 DIV 3)`,(0 xor 3) DIV 3 AS `(0 XOR 3) DIV 3`
+select 0 XOR 3 DIV 3, 0 XOR (3 DIV 3), (0 XOR 3) DIV 3 union select * from v1;
+0 XOR 3 DIV 3 0 XOR (3 DIV 3) (0 XOR 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 XOR 3 MOD 3, 2 XOR (3 MOD 3), (2 XOR 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 MOD 3 AS `2 XOR 3 MOD 3`,2 xor 3 MOD 3 AS `2 XOR (3 MOD 3)`,(2 xor 3) MOD 3 AS `(2 XOR 3) MOD 3`
+select 2 XOR 3 MOD 3, 2 XOR (3 MOD 3), (2 XOR 3) MOD 3 union select * from v1;
+2 XOR 3 MOD 3 2 XOR (3 MOD 3) (2 XOR 3) MOD 3
+1 1 0
+create or replace view v1 as select 2 XOR 3 % 3, 2 XOR (3 % 3), (2 XOR 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 MOD 3 AS `2 XOR 3 % 3`,2 xor 3 MOD 3 AS `2 XOR (3 % 3)`,(2 xor 3) MOD 3 AS `(2 XOR 3) % 3`
+select 2 XOR 3 % 3, 2 XOR (3 % 3), (2 XOR 3) % 3 union select * from v1;
+2 XOR 3 % 3 2 XOR (3 % 3) (2 XOR 3) % 3
+1 1 0
+create or replace view v1 as select 2 XOR 3 ^ 3, 2 XOR (3 ^ 3), (2 XOR 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 ^ 3 AS `2 XOR 3 ^ 3`,2 xor 3 ^ 3 AS `2 XOR (3 ^ 3)`,(2 xor 3) ^ 3 AS `(2 XOR 3) ^ 3`
+select 2 XOR 3 ^ 3, 2 XOR (3 ^ 3), (2 XOR 3) ^ 3 union select * from v1;
+2 XOR 3 ^ 3 2 XOR (3 ^ 3) (2 XOR 3) ^ 3
+1 1 3
+create or replace view v1 as select 2 XOR 3 BETWEEN 0 AND 3, 2 XOR (3 BETWEEN 0 AND 3), (2 XOR 3) BETWEEN 0 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 between 0 and 3 AS `2 XOR 3 BETWEEN 0 AND 3`,2 xor 3 between 0 and 3 AS `2 XOR (3 BETWEEN 0 AND 3)`,(2 xor 3) between 0 and 3 AS `(2 XOR 3) BETWEEN 0 AND 3`
+select 2 XOR 3 BETWEEN 0 AND 3, 2 XOR (3 BETWEEN 0 AND 3), (2 XOR 3) BETWEEN 0 AND 3 union select * from v1;
+2 XOR 3 BETWEEN 0 AND 3 2 XOR (3 BETWEEN 0 AND 3) (2 XOR 3) BETWEEN 0 AND 3
+0 0 1
+create or replace view v1 as select 0 AND 3 IS FALSE, 0 AND (3 IS FALSE), (0 AND 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 is false AS `0 AND 3 IS FALSE`,0 and 3 is false AS `0 AND (3 IS FALSE)`,(0 and 3) is false AS `(0 AND 3) IS FALSE`
+select 0 AND 3 IS FALSE, 0 AND (3 IS FALSE), (0 AND 3) IS FALSE union select * from v1;
+0 AND 3 IS FALSE 0 AND (3 IS FALSE) (0 AND 3) IS FALSE
+0 0 1
+create or replace view v1 as select charset(2 AND 3 COLLATE latin1_bin), charset(2 AND (3 COLLATE latin1_bin)), charset((2 AND 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 and 3 collate latin1_bin) AS `charset(2 AND 3 COLLATE latin1_bin)`,charset(2 and 3 collate latin1_bin) AS `charset(2 AND (3 COLLATE latin1_bin))`,charset((2 and 3) collate latin1_bin) AS `charset((2 AND 3) COLLATE latin1_bin)`
+select charset(2 AND 3 COLLATE latin1_bin), charset(2 AND (3 COLLATE latin1_bin)), charset((2 AND 3) COLLATE latin1_bin) union select * from v1;
+charset(2 AND 3 COLLATE latin1_bin) charset(2 AND (3 COLLATE latin1_bin)) charset((2 AND 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 AND 3 IN (0,1), 2 AND (3 IN (0,1)), (2 AND 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 in (0,1) AS `2 AND 3 IN (0,1)`,2 and 3 in (0,1) AS `2 AND (3 IN (0,1))`,(2 and 3) in (0,1) AS `(2 AND 3) IN (0,1)`
+select 2 AND 3 IN (0,1), 2 AND (3 IN (0,1)), (2 AND 3) IN (0,1) union select * from v1;
+2 AND 3 IN (0,1) 2 AND (3 IN (0,1)) (2 AND 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 0 AND 3 OR 3, 0 AND (3 OR 3), (0 AND 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 or 3 AS `0 AND 3 OR 3`,0 and (3 or 3) AS `0 AND (3 OR 3)`,0 and 3 or 3 AS `(0 AND 3) OR 3`
+select 0 AND 3 OR 3, 0 AND (3 OR 3), (0 AND 3) OR 3 union select * from v1;
+0 AND 3 OR 3 0 AND (3 OR 3) (0 AND 3) OR 3
+1 0 1
+create or replace view v1 as select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 or 3 AS `0 AND 3 || 3`,0 and (3 or 3) AS `0 AND (3 || 3)`,0 and 3 or 3 AS `(0 AND 3) || 3`
+select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3 union select * from v1;
+0 AND 3 || 3 0 AND (3 || 3) (0 AND 3) || 3
+1 0 1
+create or replace view v1 as select 0 AND 3 XOR 3, 0 AND (3 XOR 3), (0 AND 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 xor 3 AS `0 AND 3 XOR 3`,0 and (3 xor 3) AS `0 AND (3 XOR 3)`,0 and 3 xor 3 AS `(0 AND 3) XOR 3`
+select 0 AND 3 XOR 3, 0 AND (3 XOR 3), (0 AND 3) XOR 3 union select * from v1;
+0 AND 3 XOR 3 0 AND (3 XOR 3) (0 AND 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 AND 3 = 3, 2 AND (3 = 3), (2 AND 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 = 3 AS `2 AND 3 = 3`,2 and 3 = 3 AS `2 AND (3 = 3)`,(2 and 3) = 3 AS `(2 AND 3) = 3`
+select 2 AND 3 = 3, 2 AND (3 = 3), (2 AND 3) = 3 union select * from v1;
+2 AND 3 = 3 2 AND (3 = 3) (2 AND 3) = 3
+1 1 0
+create or replace view v1 as select 2 AND 3 <=> 3, 2 AND (3 <=> 3), (2 AND 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <=> 3 AS `2 AND 3 <=> 3`,2 and 3 <=> 3 AS `2 AND (3 <=> 3)`,(2 and 3) <=> 3 AS `(2 AND 3) <=> 3`
+select 2 AND 3 <=> 3, 2 AND (3 <=> 3), (2 AND 3) <=> 3 union select * from v1;
+2 AND 3 <=> 3 2 AND (3 <=> 3) (2 AND 3) <=> 3
+1 1 0
+create or replace view v1 as select 2 AND 3 >= 3, 2 AND (3 >= 3), (2 AND 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 >= 3 AS `2 AND 3 >= 3`,2 and 3 >= 3 AS `2 AND (3 >= 3)`,(2 and 3) >= 3 AS `(2 AND 3) >= 3`
+select 2 AND 3 >= 3, 2 AND (3 >= 3), (2 AND 3) >= 3 union select * from v1;
+2 AND 3 >= 3 2 AND (3 >= 3) (2 AND 3) >= 3
+1 1 0
+create or replace view v1 as select 2 AND 4 <= 3, 2 AND (4 <= 3), (2 AND 4) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 4 <= 3 AS `2 AND 4 <= 3`,2 and 4 <= 3 AS `2 AND (4 <= 3)`,(2 and 4) <= 3 AS `(2 AND 4) <= 3`
+select 2 AND 4 <= 3, 2 AND (4 <= 3), (2 AND 4) <= 3 union select * from v1;
+2 AND 4 <= 3 2 AND (4 <= 3) (2 AND 4) <= 3
+0 0 1
+create or replace view v1 as select 2 AND 3 < 3, 2 AND (3 < 3), (2 AND 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 < 3 AS `2 AND 3 < 3`,2 and 3 < 3 AS `2 AND (3 < 3)`,(2 and 3) < 3 AS `(2 AND 3) < 3`
+select 2 AND 3 < 3, 2 AND (3 < 3), (2 AND 3) < 3 union select * from v1;
+2 AND 3 < 3 2 AND (3 < 3) (2 AND 3) < 3
+0 0 1
+create or replace view v1 as select 2 AND 3 <> 3, 2 AND (3 <> 3), (2 AND 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <> 3 AS `2 AND 3 <> 3`,2 and 3 <> 3 AS `2 AND (3 <> 3)`,(2 and 3) <> 3 AS `(2 AND 3) <> 3`
+select 2 AND 3 <> 3, 2 AND (3 <> 3), (2 AND 3) <> 3 union select * from v1;
+2 AND 3 <> 3 2 AND (3 <> 3) (2 AND 3) <> 3
+0 0 1
+create or replace view v1 as select 2 AND 3 > 1, 2 AND (3 > 1), (2 AND 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 > 1 AS `2 AND 3 > 1`,2 and 3 > 1 AS `2 AND (3 > 1)`,(2 and 3) > 1 AS `(2 AND 3) > 1`
+select 2 AND 3 > 1, 2 AND (3 > 1), (2 AND 3) > 1 union select * from v1;
+2 AND 3 > 1 2 AND (3 > 1) (2 AND 3) > 1
+1 1 0
+create or replace view v1 as select 2 AND 3 != 3, 2 AND (3 != 3), (2 AND 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <> 3 AS `2 AND 3 != 3`,2 and 3 <> 3 AS `2 AND (3 != 3)`,(2 and 3) <> 3 AS `(2 AND 3) != 3`
+select 2 AND 3 != 3, 2 AND (3 != 3), (2 AND 3) != 3 union select * from v1;
+2 AND 3 != 3 2 AND (3 != 3) (2 AND 3) != 3
+0 0 1
+create or replace view v1 as select 2 AND 3 LIKE 3, 2 AND (3 LIKE 3), (2 AND 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 like 3 AS `2 AND 3 LIKE 3`,2 and 3 like 3 AS `2 AND (3 LIKE 3)`,(2 and 3) like 3 AS `(2 AND 3) LIKE 3`
+select 2 AND 3 LIKE 3, 2 AND (3 LIKE 3), (2 AND 3) LIKE 3 union select * from v1;
+2 AND 3 LIKE 3 2 AND (3 LIKE 3) (2 AND 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 AND 3 REGEXP 3, 2 AND (3 REGEXP 3), (2 AND 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 regexp 3 AS `2 AND 3 REGEXP 3`,2 and 3 regexp 3 AS `2 AND (3 REGEXP 3)`,(2 and 3) regexp 3 AS `(2 AND 3) REGEXP 3`
+select 2 AND 3 REGEXP 3, 2 AND (3 REGEXP 3), (2 AND 3) REGEXP 3 union select * from v1;
+2 AND 3 REGEXP 3 2 AND (3 REGEXP 3) (2 AND 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 AND 3 | 3, 2 AND (3 | 3), (2 AND 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 | 3 AS `2 AND 3 | 3`,2 and 3 | 3 AS `2 AND (3 | 3)`,(2 and 3) | 3 AS `(2 AND 3) | 3`
+select 2 AND 3 | 3, 2 AND (3 | 3), (2 AND 3) | 3 union select * from v1;
+2 AND 3 | 3 2 AND (3 | 3) (2 AND 3) | 3
+1 1 3
+create or replace view v1 as select 2 AND 2 & 2, 2 AND (2 & 2), (2 AND 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 2 & 2 AS `2 AND 2 & 2`,2 and 2 & 2 AS `2 AND (2 & 2)`,(2 and 2) & 2 AS `(2 AND 2) & 2`
+select 2 AND 2 & 2, 2 AND (2 & 2), (2 AND 2) & 2 union select * from v1;
+2 AND 2 & 2 2 AND (2 & 2) (2 AND 2) & 2
+1 1 0
+create or replace view v1 as select 2 AND 3 << 3, 2 AND (3 << 3), (2 AND 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 << 3 AS `2 AND 3 << 3`,2 and 3 << 3 AS `2 AND (3 << 3)`,(2 and 3) << 3 AS `(2 AND 3) << 3`
+select 2 AND 3 << 3, 2 AND (3 << 3), (2 AND 3) << 3 union select * from v1;
+2 AND 3 << 3 2 AND (3 << 3) (2 AND 3) << 3
+1 1 8
+create or replace view v1 as select 2 AND 3 >> 1, 2 AND (3 >> 1), (2 AND 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 >> 1 AS `2 AND 3 >> 1`,2 and 3 >> 1 AS `2 AND (3 >> 1)`,(2 and 3) >> 1 AS `(2 AND 3) >> 1`
+select 2 AND 3 >> 1, 2 AND (3 >> 1), (2 AND 3) >> 1 union select * from v1;
+2 AND 3 >> 1 2 AND (3 >> 1) (2 AND 3) >> 1
+1 1 0
+create or replace view v1 as select 2 AND '2000-01-01' +INTERVAL 1 DAY, 2 AND ('2000-01-01' +INTERVAL 1 DAY), (2 AND '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and '2000-01-01' + interval 1 day AS `2 AND '2000-01-01' +INTERVAL 1 DAY`,2 and '2000-01-01' + interval 1 day AS `2 AND ('2000-01-01' +INTERVAL 1 DAY)`,(2 and '2000-01-01') + interval 1 day AS `(2 AND '2000-01-01') +INTERVAL 1 DAY`
+select 2 AND '2000-01-01' +INTERVAL 1 DAY, 2 AND ('2000-01-01' +INTERVAL 1 DAY), (2 AND '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 AND '2000-01-01' +INTERVAL 1 DAY 2 AND ('2000-01-01' +INTERVAL 1 DAY) (2 AND '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 AND 3 + 3, 2 AND (3 + 3), (2 AND 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 + 3 AS `2 AND 3 + 3`,2 and 3 + 3 AS `2 AND (3 + 3)`,(2 and 3) + 3 AS `(2 AND 3) + 3`
+select 2 AND 3 + 3, 2 AND (3 + 3), (2 AND 3) + 3 union select * from v1;
+2 AND 3 + 3 2 AND (3 + 3) (2 AND 3) + 3
+1 1 4
+create or replace view v1 as select 2 AND 3 - 3, 2 AND (3 - 3), (2 AND 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 - 3 AS `2 AND 3 - 3`,2 and 3 - 3 AS `2 AND (3 - 3)`,(2 and 3) - 3 AS `(2 AND 3) - 3`
+select 2 AND 3 - 3, 2 AND (3 - 3), (2 AND 3) - 3 union select * from v1;
+2 AND 3 - 3 2 AND (3 - 3) (2 AND 3) - 3
+0 0 -2
+create or replace view v1 as select 2 AND 3 * 3, 2 AND (3 * 3), (2 AND 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 * 3 AS `2 AND 3 * 3`,2 and 3 * 3 AS `2 AND (3 * 3)`,(2 and 3) * 3 AS `(2 AND 3) * 3`
+select 2 AND 3 * 3, 2 AND (3 * 3), (2 AND 3) * 3 union select * from v1;
+2 AND 3 * 3 2 AND (3 * 3) (2 AND 3) * 3
+1 1 3
+create or replace view v1 as select 2 AND 3 / 3, 2 AND (3 / 3), (2 AND 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 / 3 AS `2 AND 3 / 3`,2 and 3 / 3 AS `2 AND (3 / 3)`,(2 and 3) / 3 AS `(2 AND 3) / 3`
+select 2 AND 3 / 3, 2 AND (3 / 3), (2 AND 3) / 3 union select * from v1;
+2 AND 3 / 3 2 AND (3 / 3) (2 AND 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 AND 3 DIV 3, 2 AND (3 DIV 3), (2 AND 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 DIV 3 AS `2 AND 3 DIV 3`,2 and 3 DIV 3 AS `2 AND (3 DIV 3)`,(2 and 3) DIV 3 AS `(2 AND 3) DIV 3`
+select 2 AND 3 DIV 3, 2 AND (3 DIV 3), (2 AND 3) DIV 3 union select * from v1;
+2 AND 3 DIV 3 2 AND (3 DIV 3) (2 AND 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 AND 3 MOD 3, 2 AND (3 MOD 3), (2 AND 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 MOD 3 AS `2 AND 3 MOD 3`,2 and 3 MOD 3 AS `2 AND (3 MOD 3)`,(2 and 3) MOD 3 AS `(2 AND 3) MOD 3`
+select 2 AND 3 MOD 3, 2 AND (3 MOD 3), (2 AND 3) MOD 3 union select * from v1;
+2 AND 3 MOD 3 2 AND (3 MOD 3) (2 AND 3) MOD 3
+0 0 1
+create or replace view v1 as select 2 AND 3 % 3, 2 AND (3 % 3), (2 AND 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 MOD 3 AS `2 AND 3 % 3`,2 and 3 MOD 3 AS `2 AND (3 % 3)`,(2 and 3) MOD 3 AS `(2 AND 3) % 3`
+select 2 AND 3 % 3, 2 AND (3 % 3), (2 AND 3) % 3 union select * from v1;
+2 AND 3 % 3 2 AND (3 % 3) (2 AND 3) % 3
+0 0 1
+create or replace view v1 as select 2 AND 3 ^ 3, 2 AND (3 ^ 3), (2 AND 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 ^ 3 AS `2 AND 3 ^ 3`,2 and 3 ^ 3 AS `2 AND (3 ^ 3)`,(2 and 3) ^ 3 AS `(2 AND 3) ^ 3`
+select 2 AND 3 ^ 3, 2 AND (3 ^ 3), (2 AND 3) ^ 3 union select * from v1;
+2 AND 3 ^ 3 2 AND (3 ^ 3) (2 AND 3) ^ 3
+0 0 2
+create or replace view v1 as select 2 AND 3 BETWEEN 2 AND 3, 2 AND (3 BETWEEN 2 AND 3), (2 AND 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 between 2 and 3 AS `2 AND 3 BETWEEN 2 AND 3`,2 and 3 between 2 and 3 AS `2 AND (3 BETWEEN 2 AND 3)`,(2 and 3) between 2 and 3 AS `(2 AND 3) BETWEEN 2 AND 3`
+select 2 AND 3 BETWEEN 2 AND 3, 2 AND (3 BETWEEN 2 AND 3), (2 AND 3) BETWEEN 2 AND 3 union select * from v1;
+2 AND 3 BETWEEN 2 AND 3 2 AND (3 BETWEEN 2 AND 3) (2 AND 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select 0 && 3 IS FALSE, 0 && (3 IS FALSE), (0 && 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 is false AS `0 && 3 IS FALSE`,0 and 3 is false AS `0 && (3 IS FALSE)`,(0 and 3) is false AS `(0 && 3) IS FALSE`
+select 0 && 3 IS FALSE, 0 && (3 IS FALSE), (0 && 3) IS FALSE union select * from v1;
+0 && 3 IS FALSE 0 && (3 IS FALSE) (0 && 3) IS FALSE
+0 0 1
+create or replace view v1 as select charset(2 && 3 COLLATE latin1_bin), charset(2 && (3 COLLATE latin1_bin)), charset((2 && 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 and 3 collate latin1_bin) AS `charset(2 && 3 COLLATE latin1_bin)`,charset(2 and 3 collate latin1_bin) AS `charset(2 && (3 COLLATE latin1_bin))`,charset((2 and 3) collate latin1_bin) AS `charset((2 && 3) COLLATE latin1_bin)`
+select charset(2 && 3 COLLATE latin1_bin), charset(2 && (3 COLLATE latin1_bin)), charset((2 && 3) COLLATE latin1_bin) union select * from v1;
+charset(2 && 3 COLLATE latin1_bin) charset(2 && (3 COLLATE latin1_bin)) charset((2 && 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 && 3 IN (0,1), 2 && (3 IN (0,1)), (2 && 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 in (0,1) AS `2 && 3 IN (0,1)`,2 and 3 in (0,1) AS `2 && (3 IN (0,1))`,(2 and 3) in (0,1) AS `(2 && 3) IN (0,1)`
+select 2 && 3 IN (0,1), 2 && (3 IN (0,1)), (2 && 3) IN (0,1) union select * from v1;
+2 && 3 IN (0,1) 2 && (3 IN (0,1)) (2 && 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 0 && 3 OR 3, 0 && (3 OR 3), (0 && 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 or 3 AS `0 && 3 OR 3`,0 and (3 or 3) AS `0 && (3 OR 3)`,0 and 3 or 3 AS `(0 && 3) OR 3`
+select 0 && 3 OR 3, 0 && (3 OR 3), (0 && 3) OR 3 union select * from v1;
+0 && 3 OR 3 0 && (3 OR 3) (0 && 3) OR 3
+1 0 1
+create or replace view v1 as select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 or 3 AS `0 && 3 || 3`,0 and (3 or 3) AS `0 && (3 || 3)`,0 and 3 or 3 AS `(0 && 3) || 3`
+select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3 union select * from v1;
+0 && 3 || 3 0 && (3 || 3) (0 && 3) || 3
+1 0 1
+create or replace view v1 as select 0 && 3 XOR 3, 0 && (3 XOR 3), (0 && 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and 3 xor 3 AS `0 && 3 XOR 3`,0 and (3 xor 3) AS `0 && (3 XOR 3)`,0 and 3 xor 3 AS `(0 && 3) XOR 3`
+select 0 && 3 XOR 3, 0 && (3 XOR 3), (0 && 3) XOR 3 union select * from v1;
+0 && 3 XOR 3 0 && (3 XOR 3) (0 && 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 && 3 = 3, 2 && (3 = 3), (2 && 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 = 3 AS `2 && 3 = 3`,2 and 3 = 3 AS `2 && (3 = 3)`,(2 and 3) = 3 AS `(2 && 3) = 3`
+select 2 && 3 = 3, 2 && (3 = 3), (2 && 3) = 3 union select * from v1;
+2 && 3 = 3 2 && (3 = 3) (2 && 3) = 3
+1 1 0
+create or replace view v1 as select 2 && 3 <=> 3, 2 && (3 <=> 3), (2 && 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <=> 3 AS `2 && 3 <=> 3`,2 and 3 <=> 3 AS `2 && (3 <=> 3)`,(2 and 3) <=> 3 AS `(2 && 3) <=> 3`
+select 2 && 3 <=> 3, 2 && (3 <=> 3), (2 && 3) <=> 3 union select * from v1;
+2 && 3 <=> 3 2 && (3 <=> 3) (2 && 3) <=> 3
+1 1 0
+create or replace view v1 as select 2 && 3 >= 3, 2 && (3 >= 3), (2 && 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 >= 3 AS `2 && 3 >= 3`,2 and 3 >= 3 AS `2 && (3 >= 3)`,(2 and 3) >= 3 AS `(2 && 3) >= 3`
+select 2 && 3 >= 3, 2 && (3 >= 3), (2 && 3) >= 3 union select * from v1;
+2 && 3 >= 3 2 && (3 >= 3) (2 && 3) >= 3
+1 1 0
+create or replace view v1 as select 2 && 4 <= 3, 2 && (4 <= 3), (2 && 4) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 4 <= 3 AS `2 && 4 <= 3`,2 and 4 <= 3 AS `2 && (4 <= 3)`,(2 and 4) <= 3 AS `(2 && 4) <= 3`
+select 2 && 4 <= 3, 2 && (4 <= 3), (2 && 4) <= 3 union select * from v1;
+2 && 4 <= 3 2 && (4 <= 3) (2 && 4) <= 3
+0 0 1
+create or replace view v1 as select 2 && 3 < 3, 2 && (3 < 3), (2 && 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 < 3 AS `2 && 3 < 3`,2 and 3 < 3 AS `2 && (3 < 3)`,(2 and 3) < 3 AS `(2 && 3) < 3`
+select 2 && 3 < 3, 2 && (3 < 3), (2 && 3) < 3 union select * from v1;
+2 && 3 < 3 2 && (3 < 3) (2 && 3) < 3
+0 0 1
+create or replace view v1 as select 2 && 3 <> 3, 2 && (3 <> 3), (2 && 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <> 3 AS `2 && 3 <> 3`,2 and 3 <> 3 AS `2 && (3 <> 3)`,(2 and 3) <> 3 AS `(2 && 3) <> 3`
+select 2 && 3 <> 3, 2 && (3 <> 3), (2 && 3) <> 3 union select * from v1;
+2 && 3 <> 3 2 && (3 <> 3) (2 && 3) <> 3
+0 0 1
+create or replace view v1 as select 2 && 3 > 1, 2 && (3 > 1), (2 && 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 > 1 AS `2 && 3 > 1`,2 and 3 > 1 AS `2 && (3 > 1)`,(2 and 3) > 1 AS `(2 && 3) > 1`
+select 2 && 3 > 1, 2 && (3 > 1), (2 && 3) > 1 union select * from v1;
+2 && 3 > 1 2 && (3 > 1) (2 && 3) > 1
+1 1 0
+create or replace view v1 as select 2 && 3 != 3, 2 && (3 != 3), (2 && 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 <> 3 AS `2 && 3 != 3`,2 and 3 <> 3 AS `2 && (3 != 3)`,(2 and 3) <> 3 AS `(2 && 3) != 3`
+select 2 && 3 != 3, 2 && (3 != 3), (2 && 3) != 3 union select * from v1;
+2 && 3 != 3 2 && (3 != 3) (2 && 3) != 3
+0 0 1
+create or replace view v1 as select 2 && 3 LIKE 3, 2 && (3 LIKE 3), (2 && 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 like 3 AS `2 && 3 LIKE 3`,2 and 3 like 3 AS `2 && (3 LIKE 3)`,(2 and 3) like 3 AS `(2 && 3) LIKE 3`
+select 2 && 3 LIKE 3, 2 && (3 LIKE 3), (2 && 3) LIKE 3 union select * from v1;
+2 && 3 LIKE 3 2 && (3 LIKE 3) (2 && 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 && 3 REGEXP 3, 2 && (3 REGEXP 3), (2 && 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 regexp 3 AS `2 && 3 REGEXP 3`,2 and 3 regexp 3 AS `2 && (3 REGEXP 3)`,(2 and 3) regexp 3 AS `(2 && 3) REGEXP 3`
+select 2 && 3 REGEXP 3, 2 && (3 REGEXP 3), (2 && 3) REGEXP 3 union select * from v1;
+2 && 3 REGEXP 3 2 && (3 REGEXP 3) (2 && 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 && 3 | 3, 2 && (3 | 3), (2 && 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 | 3 AS `2 && 3 | 3`,2 and 3 | 3 AS `2 && (3 | 3)`,(2 and 3) | 3 AS `(2 && 3) | 3`
+select 2 && 3 | 3, 2 && (3 | 3), (2 && 3) | 3 union select * from v1;
+2 && 3 | 3 2 && (3 | 3) (2 && 3) | 3
+1 1 3
+create or replace view v1 as select 2 && 2 & 2, 2 && (2 & 2), (2 && 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 2 & 2 AS `2 && 2 & 2`,2 and 2 & 2 AS `2 && (2 & 2)`,(2 and 2) & 2 AS `(2 && 2) & 2`
+select 2 && 2 & 2, 2 && (2 & 2), (2 && 2) & 2 union select * from v1;
+2 && 2 & 2 2 && (2 & 2) (2 && 2) & 2
+1 1 0
+create or replace view v1 as select 2 && 3 << 3, 2 && (3 << 3), (2 && 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 << 3 AS `2 && 3 << 3`,2 and 3 << 3 AS `2 && (3 << 3)`,(2 and 3) << 3 AS `(2 && 3) << 3`
+select 2 && 3 << 3, 2 && (3 << 3), (2 && 3) << 3 union select * from v1;
+2 && 3 << 3 2 && (3 << 3) (2 && 3) << 3
+1 1 8
+create or replace view v1 as select 2 && 3 >> 1, 2 && (3 >> 1), (2 && 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 >> 1 AS `2 && 3 >> 1`,2 and 3 >> 1 AS `2 && (3 >> 1)`,(2 and 3) >> 1 AS `(2 && 3) >> 1`
+select 2 && 3 >> 1, 2 && (3 >> 1), (2 && 3) >> 1 union select * from v1;
+2 && 3 >> 1 2 && (3 >> 1) (2 && 3) >> 1
+1 1 0
+create or replace view v1 as select 2 && '2000-01-01' +INTERVAL 1 DAY, 2 && ('2000-01-01' +INTERVAL 1 DAY), (2 && '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and '2000-01-01' + interval 1 day AS `2 && '2000-01-01' +INTERVAL 1 DAY`,2 and '2000-01-01' + interval 1 day AS `2 && ('2000-01-01' +INTERVAL 1 DAY)`,(2 and '2000-01-01') + interval 1 day AS `(2 && '2000-01-01') +INTERVAL 1 DAY`
+select 2 && '2000-01-01' +INTERVAL 1 DAY, 2 && ('2000-01-01' +INTERVAL 1 DAY), (2 && '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 && '2000-01-01' +INTERVAL 1 DAY 2 && ('2000-01-01' +INTERVAL 1 DAY) (2 && '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 && 3 + 3, 2 && (3 + 3), (2 && 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 + 3 AS `2 && 3 + 3`,2 and 3 + 3 AS `2 && (3 + 3)`,(2 and 3) + 3 AS `(2 && 3) + 3`
+select 2 && 3 + 3, 2 && (3 + 3), (2 && 3) + 3 union select * from v1;
+2 && 3 + 3 2 && (3 + 3) (2 && 3) + 3
+1 1 4
+create or replace view v1 as select 2 && 3 - 3, 2 && (3 - 3), (2 && 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 - 3 AS `2 && 3 - 3`,2 and 3 - 3 AS `2 && (3 - 3)`,(2 and 3) - 3 AS `(2 && 3) - 3`
+select 2 && 3 - 3, 2 && (3 - 3), (2 && 3) - 3 union select * from v1;
+2 && 3 - 3 2 && (3 - 3) (2 && 3) - 3
+0 0 -2
+create or replace view v1 as select 2 && 3 * 3, 2 && (3 * 3), (2 && 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 * 3 AS `2 && 3 * 3`,2 and 3 * 3 AS `2 && (3 * 3)`,(2 and 3) * 3 AS `(2 && 3) * 3`
+select 2 && 3 * 3, 2 && (3 * 3), (2 && 3) * 3 union select * from v1;
+2 && 3 * 3 2 && (3 * 3) (2 && 3) * 3
+1 1 3
+create or replace view v1 as select 2 && 3 / 3, 2 && (3 / 3), (2 && 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 / 3 AS `2 && 3 / 3`,2 and 3 / 3 AS `2 && (3 / 3)`,(2 and 3) / 3 AS `(2 && 3) / 3`
+select 2 && 3 / 3, 2 && (3 / 3), (2 && 3) / 3 union select * from v1;
+2 && 3 / 3 2 && (3 / 3) (2 && 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 && 3 DIV 3, 2 && (3 DIV 3), (2 && 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 DIV 3 AS `2 && 3 DIV 3`,2 and 3 DIV 3 AS `2 && (3 DIV 3)`,(2 and 3) DIV 3 AS `(2 && 3) DIV 3`
+select 2 && 3 DIV 3, 2 && (3 DIV 3), (2 && 3) DIV 3 union select * from v1;
+2 && 3 DIV 3 2 && (3 DIV 3) (2 && 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 && 3 MOD 3, 2 && (3 MOD 3), (2 && 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 MOD 3 AS `2 && 3 MOD 3`,2 and 3 MOD 3 AS `2 && (3 MOD 3)`,(2 and 3) MOD 3 AS `(2 && 3) MOD 3`
+select 2 && 3 MOD 3, 2 && (3 MOD 3), (2 && 3) MOD 3 union select * from v1;
+2 && 3 MOD 3 2 && (3 MOD 3) (2 && 3) MOD 3
+0 0 1
+create or replace view v1 as select 2 && 3 % 3, 2 && (3 % 3), (2 && 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 MOD 3 AS `2 && 3 % 3`,2 and 3 MOD 3 AS `2 && (3 % 3)`,(2 and 3) MOD 3 AS `(2 && 3) % 3`
+select 2 && 3 % 3, 2 && (3 % 3), (2 && 3) % 3 union select * from v1;
+2 && 3 % 3 2 && (3 % 3) (2 && 3) % 3
+0 0 1
+create or replace view v1 as select 2 && 3 ^ 3, 2 && (3 ^ 3), (2 && 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 ^ 3 AS `2 && 3 ^ 3`,2 and 3 ^ 3 AS `2 && (3 ^ 3)`,(2 and 3) ^ 3 AS `(2 && 3) ^ 3`
+select 2 && 3 ^ 3, 2 && (3 ^ 3), (2 && 3) ^ 3 union select * from v1;
+2 && 3 ^ 3 2 && (3 ^ 3) (2 && 3) ^ 3
+0 0 2
+create or replace view v1 as select 2 && 3 BETWEEN 2 AND 3, 2 && (3 BETWEEN 2 AND 3), (2 && 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 between 2 and 3 AS `2 && 3 BETWEEN 2 AND 3`,2 and 3 between 2 and 3 AS `2 && (3 BETWEEN 2 AND 3)`,(2 and 3) between 2 and 3 AS `(2 && 3) BETWEEN 2 AND 3`
+select 2 && 3 BETWEEN 2 AND 3, 2 && (3 BETWEEN 2 AND 3), (2 && 3) BETWEEN 2 AND 3 union select * from v1;
+2 && 3 BETWEEN 2 AND 3 2 && (3 BETWEEN 2 AND 3) (2 && 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select 2 = 3 IS FALSE, 2 = (3 IS FALSE), (2 = 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 is false AS `2 = 3 IS FALSE`,2 = (3 is false) AS `2 = (3 IS FALSE)`,2 = 3 is false AS `(2 = 3) IS FALSE`
+select 2 = 3 IS FALSE, 2 = (3 IS FALSE), (2 = 3) IS FALSE union select * from v1;
+2 = 3 IS FALSE 2 = (3 IS FALSE) (2 = 3) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 = 3 COLLATE latin1_bin), charset(2 = (3 COLLATE latin1_bin)), charset((2 = 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 = 3 collate latin1_bin) AS `charset(2 = 3 COLLATE latin1_bin)`,charset(2 = 3 collate latin1_bin) AS `charset(2 = (3 COLLATE latin1_bin))`,charset((2 = 3) collate latin1_bin) AS `charset((2 = 3) COLLATE latin1_bin)`
+select charset(2 = 3 COLLATE latin1_bin), charset(2 = (3 COLLATE latin1_bin)), charset((2 = 3) COLLATE latin1_bin) union select * from v1;
+charset(2 = 3 COLLATE latin1_bin) charset(2 = (3 COLLATE latin1_bin)) charset((2 = 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 = 3 IN (0,1), 2 = (3 IN (0,1)), (2 = 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 in (0,1) AS `2 = 3 IN (0,1)`,2 = 3 in (0,1) AS `2 = (3 IN (0,1))`,(2 = 3) in (0,1) AS `(2 = 3) IN (0,1)`
+select 2 = 3 IN (0,1), 2 = (3 IN (0,1)), (2 = 3) IN (0,1) union select * from v1;
+2 = 3 IN (0,1) 2 = (3 IN (0,1)) (2 = 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 2 = 3 OR 3, 2 = (3 OR 3), (2 = 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 or 3 AS `2 = 3 OR 3`,2 = (3 or 3) AS `2 = (3 OR 3)`,2 = 3 or 3 AS `(2 = 3) OR 3`
+select 2 = 3 OR 3, 2 = (3 OR 3), (2 = 3) OR 3 union select * from v1;
+2 = 3 OR 3 2 = (3 OR 3) (2 = 3) OR 3
+1 0 1
+create or replace view v1 as select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 or 3 AS `2 = 3 || 3`,2 = (3 or 3) AS `2 = (3 || 3)`,2 = 3 or 3 AS `(2 = 3) || 3`
+select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3 union select * from v1;
+2 = 3 || 3 2 = (3 || 3) (2 = 3) || 3
+1 0 1
+create or replace view v1 as select 2 = 3 XOR 3, 2 = (3 XOR 3), (2 = 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 xor 3 AS `2 = 3 XOR 3`,2 = (3 xor 3) AS `2 = (3 XOR 3)`,2 = 3 xor 3 AS `(2 = 3) XOR 3`
+select 2 = 3 XOR 3, 2 = (3 XOR 3), (2 = 3) XOR 3 union select * from v1;
+2 = 3 XOR 3 2 = (3 XOR 3) (2 = 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 = 2 AND 2, 2 = (2 AND 2), (2 = 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 2 and 2 AS `2 = 2 AND 2`,2 = (2 and 2) AS `2 = (2 AND 2)`,2 = 2 and 2 AS `(2 = 2) AND 2`
+select 2 = 2 AND 2, 2 = (2 AND 2), (2 = 2) AND 2 union select * from v1;
+2 = 2 AND 2 2 = (2 AND 2) (2 = 2) AND 2
+1 0 1
+create or replace view v1 as select 2 = 2 && 2, 2 = (2 && 2), (2 = 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 2 and 2 AS `2 = 2 && 2`,2 = (2 and 2) AS `2 = (2 && 2)`,2 = 2 and 2 AS `(2 = 2) && 2`
+select 2 = 2 && 2, 2 = (2 && 2), (2 = 2) && 2 union select * from v1;
+2 = 2 && 2 2 = (2 && 2) (2 = 2) && 2
+1 0 1
+create or replace view v1 as select 1 = 3 = 3, 1 = (3 = 3), (1 = 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 = 3 AS `1 = 3 = 3`,1 = (3 = 3) AS `1 = (3 = 3)`,1 = 3 = 3 AS `(1 = 3) = 3`
+select 1 = 3 = 3, 1 = (3 = 3), (1 = 3) = 3 union select * from v1;
+1 = 3 = 3 1 = (3 = 3) (1 = 3) = 3
+0 1 0
+create or replace view v1 as select 1 = 3 <=> 3, 1 = (3 <=> 3), (1 = 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 <=> 3 AS `1 = 3 <=> 3`,1 = (3 <=> 3) AS `1 = (3 <=> 3)`,1 = 3 <=> 3 AS `(1 = 3) <=> 3`
+select 1 = 3 <=> 3, 1 = (3 <=> 3), (1 = 3) <=> 3 union select * from v1;
+1 = 3 <=> 3 1 = (3 <=> 3) (1 = 3) <=> 3
+0 1 0
+create or replace view v1 as select 1 = 3 >= 3, 1 = (3 >= 3), (1 = 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 >= 3 AS `1 = 3 >= 3`,1 = (3 >= 3) AS `1 = (3 >= 3)`,1 = 3 >= 3 AS `(1 = 3) >= 3`
+select 1 = 3 >= 3, 1 = (3 >= 3), (1 = 3) >= 3 union select * from v1;
+1 = 3 >= 3 1 = (3 >= 3) (1 = 3) >= 3
+0 1 0
+create or replace view v1 as select 2 = 3 <= 3, 2 = (3 <= 3), (2 = 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 <= 3 AS `2 = 3 <= 3`,2 = (3 <= 3) AS `2 = (3 <= 3)`,2 = 3 <= 3 AS `(2 = 3) <= 3`
+select 2 = 3 <= 3, 2 = (3 <= 3), (2 = 3) <= 3 union select * from v1;
+2 = 3 <= 3 2 = (3 <= 3) (2 = 3) <= 3
+1 0 1
+create or replace view v1 as select 2 = 3 < 3, 2 = (3 < 3), (2 = 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 < 3 AS `2 = 3 < 3`,2 = (3 < 3) AS `2 = (3 < 3)`,2 = 3 < 3 AS `(2 = 3) < 3`
+select 2 = 3 < 3, 2 = (3 < 3), (2 = 3) < 3 union select * from v1;
+2 = 3 < 3 2 = (3 < 3) (2 = 3) < 3
+1 0 1
+create or replace view v1 as select 2 = 3 <> 3, 2 = (3 <> 3), (2 = 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 <> 3 AS `2 = 3 <> 3`,2 = (3 <> 3) AS `2 = (3 <> 3)`,2 = 3 <> 3 AS `(2 = 3) <> 3`
+select 2 = 3 <> 3, 2 = (3 <> 3), (2 = 3) <> 3 union select * from v1;
+2 = 3 <> 3 2 = (3 <> 3) (2 = 3) <> 3
+1 0 1
+create or replace view v1 as select 0 = 3 > 3, 0 = (3 > 3), (0 = 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 = 3 > 3 AS `0 = 3 > 3`,0 = (3 > 3) AS `0 = (3 > 3)`,0 = 3 > 3 AS `(0 = 3) > 3`
+select 0 = 3 > 3, 0 = (3 > 3), (0 = 3) > 3 union select * from v1;
+0 = 3 > 3 0 = (3 > 3) (0 = 3) > 3
+0 1 0
+create or replace view v1 as select 2 = 3 != 3, 2 = (3 != 3), (2 = 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 <> 3 AS `2 = 3 != 3`,2 = (3 <> 3) AS `2 = (3 != 3)`,2 = 3 <> 3 AS `(2 = 3) != 3`
+select 2 = 3 != 3, 2 = (3 != 3), (2 = 3) != 3 union select * from v1;
+2 = 3 != 3 2 = (3 != 3) (2 = 3) != 3
+1 0 1
+create or replace view v1 as select 1 = 3 LIKE 3, 1 = (3 LIKE 3), (1 = 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 like 3 AS `1 = 3 LIKE 3`,1 = 3 like 3 AS `1 = (3 LIKE 3)`,(1 = 3) like 3 AS `(1 = 3) LIKE 3`
+select 1 = 3 LIKE 3, 1 = (3 LIKE 3), (1 = 3) LIKE 3 union select * from v1;
+1 = 3 LIKE 3 1 = (3 LIKE 3) (1 = 3) LIKE 3
+1 1 0
+create or replace view v1 as select 1 = 3 REGEXP 3, 1 = (3 REGEXP 3), (1 = 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 regexp 3 AS `1 = 3 REGEXP 3`,1 = 3 regexp 3 AS `1 = (3 REGEXP 3)`,(1 = 3) regexp 3 AS `(1 = 3) REGEXP 3`
+select 1 = 3 REGEXP 3, 1 = (3 REGEXP 3), (1 = 3) REGEXP 3 union select * from v1;
+1 = 3 REGEXP 3 1 = (3 REGEXP 3) (1 = 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 = 3 | 3, 2 = (3 | 3), (2 = 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 | 3 AS `2 = 3 | 3`,2 = 3 | 3 AS `2 = (3 | 3)`,(2 = 3) | 3 AS `(2 = 3) | 3`
+select 2 = 3 | 3, 2 = (3 | 3), (2 = 3) | 3 union select * from v1;
+2 = 3 | 3 2 = (3 | 3) (2 = 3) | 3
+0 0 3
+create or replace view v1 as select 2 = 3 & 2, 2 = (3 & 2), (2 = 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 & 2 AS `2 = 3 & 2`,2 = 3 & 2 AS `2 = (3 & 2)`,(2 = 3) & 2 AS `(2 = 3) & 2`
+select 2 = 3 & 2, 2 = (3 & 2), (2 = 3) & 2 union select * from v1;
+2 = 3 & 2 2 = (3 & 2) (2 = 3) & 2
+1 1 0
+create or replace view v1 as select 3 = 3 << 3, 3 = (3 << 3), (3 = 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 3 << 3 AS `3 = 3 << 3`,3 = 3 << 3 AS `3 = (3 << 3)`,(3 = 3) << 3 AS `(3 = 3) << 3`
+select 3 = 3 << 3, 3 = (3 << 3), (3 = 3) << 3 union select * from v1;
+3 = 3 << 3 3 = (3 << 3) (3 = 3) << 3
+0 0 8
+create or replace view v1 as select 1 = 3 >> 1, 1 = (3 >> 1), (1 = 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 >> 1 AS `1 = 3 >> 1`,1 = 3 >> 1 AS `1 = (3 >> 1)`,(1 = 3) >> 1 AS `(1 = 3) >> 1`
+select 1 = 3 >> 1, 1 = (3 >> 1), (1 = 3) >> 1 union select * from v1;
+1 = 3 >> 1 1 = (3 >> 1) (1 = 3) >> 1
+1 1 0
+create or replace view v1 as select 2 = '2000-01-01' +INTERVAL 1 DAY, 2 = ('2000-01-01' +INTERVAL 1 DAY), (2 = '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = '2000-01-01' + interval 1 day AS `2 = '2000-01-01' +INTERVAL 1 DAY`,2 = '2000-01-01' + interval 1 day AS `2 = ('2000-01-01' +INTERVAL 1 DAY)`,(2 = '2000-01-01') + interval 1 day AS `(2 = '2000-01-01') +INTERVAL 1 DAY`
+select 2 = '2000-01-01' +INTERVAL 1 DAY, 2 = ('2000-01-01' +INTERVAL 1 DAY), (2 = '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 = '2000-01-01' +INTERVAL 1 DAY 2 = ('2000-01-01' +INTERVAL 1 DAY) (2 = '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 = 3 + 3, 2 = (3 + 3), (2 = 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 + 3 AS `2 = 3 + 3`,2 = 3 + 3 AS `2 = (3 + 3)`,(2 = 3) + 3 AS `(2 = 3) + 3`
+select 2 = 3 + 3, 2 = (3 + 3), (2 = 3) + 3 union select * from v1;
+2 = 3 + 3 2 = (3 + 3) (2 = 3) + 3
+0 0 3
+create or replace view v1 as select 2 = 3 - 3, 2 = (3 - 3), (2 = 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 - 3 AS `2 = 3 - 3`,2 = 3 - 3 AS `2 = (3 - 3)`,(2 = 3) - 3 AS `(2 = 3) - 3`
+select 2 = 3 - 3, 2 = (3 - 3), (2 = 3) - 3 union select * from v1;
+2 = 3 - 3 2 = (3 - 3) (2 = 3) - 3
+0 0 -3
+create or replace view v1 as select 3 = 3 * 3, 3 = (3 * 3), (3 = 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 3 * 3 AS `3 = 3 * 3`,3 = 3 * 3 AS `3 = (3 * 3)`,(3 = 3) * 3 AS `(3 = 3) * 3`
+select 3 = 3 * 3, 3 = (3 * 3), (3 = 3) * 3 union select * from v1;
+3 = 3 * 3 3 = (3 * 3) (3 = 3) * 3
+0 0 3
+create or replace view v1 as select 3 = 9 / 3, 3 = (9 / 3), (3 = 9) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 9 / 3 AS `3 = 9 / 3`,3 = 9 / 3 AS `3 = (9 / 3)`,(3 = 9) / 3 AS `(3 = 9) / 3`
+select 3 = 9 / 3, 3 = (9 / 3), (3 = 9) / 3 union select * from v1;
+3 = 9 / 3 3 = (9 / 3) (3 = 9) / 3
+1 1 0.0000
+create or replace view v1 as select 3 = 9 DIV 3, 3 = (9 DIV 3), (3 = 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 9 DIV 3 AS `3 = 9 DIV 3`,3 = 9 DIV 3 AS `3 = (9 DIV 3)`,(3 = 9) DIV 3 AS `(3 = 9) DIV 3`
+select 3 = 9 DIV 3, 3 = (9 DIV 3), (3 = 9) DIV 3 union select * from v1;
+3 = 9 DIV 3 3 = (9 DIV 3) (3 = 9) DIV 3
+1 1 0
+create or replace view v1 as select 3 = 3 MOD 3, 3 = (3 MOD 3), (3 = 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 3 MOD 3 AS `3 = 3 MOD 3`,3 = 3 MOD 3 AS `3 = (3 MOD 3)`,(3 = 3) MOD 3 AS `(3 = 3) MOD 3`
+select 3 = 3 MOD 3, 3 = (3 MOD 3), (3 = 3) MOD 3 union select * from v1;
+3 = 3 MOD 3 3 = (3 MOD 3) (3 = 3) MOD 3
+0 0 1
+create or replace view v1 as select 3 = 3 % 3, 3 = (3 % 3), (3 = 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 = 3 MOD 3 AS `3 = 3 % 3`,3 = 3 MOD 3 AS `3 = (3 % 3)`,(3 = 3) MOD 3 AS `(3 = 3) % 3`
+select 3 = 3 % 3, 3 = (3 % 3), (3 = 3) % 3 union select * from v1;
+3 = 3 % 3 3 = (3 % 3) (3 = 3) % 3
+0 0 1
+create or replace view v1 as select 2 = 3 ^ 3, 2 = (3 ^ 3), (2 = 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 ^ 3 AS `2 = 3 ^ 3`,2 = 3 ^ 3 AS `2 = (3 ^ 3)`,(2 = 3) ^ 3 AS `(2 = 3) ^ 3`
+select 2 = 3 ^ 3, 2 = (3 ^ 3), (2 = 3) ^ 3 union select * from v1;
+2 = 3 ^ 3 2 = (3 ^ 3) (2 = 3) ^ 3
+0 0 3
+create or replace view v1 as select 1 = 3 BETWEEN 1 AND 3, 1 = (3 BETWEEN 1 AND 3), (1 = 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 = 3 between 1 and 3 AS `1 = 3 BETWEEN 1 AND 3`,1 = 3 between 1 and 3 AS `1 = (3 BETWEEN 1 AND 3)`,(1 = 3) between 1 and 3 AS `(1 = 3) BETWEEN 1 AND 3`
+select 1 = 3 BETWEEN 1 AND 3, 1 = (3 BETWEEN 1 AND 3), (1 = 3) BETWEEN 1 AND 3 union select * from v1;
+1 = 3 BETWEEN 1 AND 3 1 = (3 BETWEEN 1 AND 3) (1 = 3) BETWEEN 1 AND 3
+1 1 0
+create or replace view v1 as select 2 <=> 3 IS FALSE, 2 <=> (3 IS FALSE), (2 <=> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 is false AS `2 <=> 3 IS FALSE`,2 <=> (3 is false) AS `2 <=> (3 IS FALSE)`,2 <=> 3 is false AS `(2 <=> 3) IS FALSE`
+select 2 <=> 3 IS FALSE, 2 <=> (3 IS FALSE), (2 <=> 3) IS FALSE union select * from v1;
+2 <=> 3 IS FALSE 2 <=> (3 IS FALSE) (2 <=> 3) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 <=> 3 COLLATE latin1_bin), charset(2 <=> (3 COLLATE latin1_bin)), charset((2 <=> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 <=> 3 collate latin1_bin) AS `charset(2 <=> 3 COLLATE latin1_bin)`,charset(2 <=> 3 collate latin1_bin) AS `charset(2 <=> (3 COLLATE latin1_bin))`,charset((2 <=> 3) collate latin1_bin) AS `charset((2 <=> 3) COLLATE latin1_bin)`
+select charset(2 <=> 3 COLLATE latin1_bin), charset(2 <=> (3 COLLATE latin1_bin)), charset((2 <=> 3) COLLATE latin1_bin) union select * from v1;
+charset(2 <=> 3 COLLATE latin1_bin) charset(2 <=> (3 COLLATE latin1_bin)) charset((2 <=> 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 <=> 3 IN (0,1), 2 <=> (3 IN (0,1)), (2 <=> 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 in (0,1) AS `2 <=> 3 IN (0,1)`,2 <=> 3 in (0,1) AS `2 <=> (3 IN (0,1))`,(2 <=> 3) in (0,1) AS `(2 <=> 3) IN (0,1)`
+select 2 <=> 3 IN (0,1), 2 <=> (3 IN (0,1)), (2 <=> 3) IN (0,1) union select * from v1;
+2 <=> 3 IN (0,1) 2 <=> (3 IN (0,1)) (2 <=> 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 2 <=> 3 OR 3, 2 <=> (3 OR 3), (2 <=> 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 or 3 AS `2 <=> 3 OR 3`,2 <=> (3 or 3) AS `2 <=> (3 OR 3)`,2 <=> 3 or 3 AS `(2 <=> 3) OR 3`
+select 2 <=> 3 OR 3, 2 <=> (3 OR 3), (2 <=> 3) OR 3 union select * from v1;
+2 <=> 3 OR 3 2 <=> (3 OR 3) (2 <=> 3) OR 3
+1 0 1
+create or replace view v1 as select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 or 3 AS `2 <=> 3 || 3`,2 <=> (3 or 3) AS `2 <=> (3 || 3)`,2 <=> 3 or 3 AS `(2 <=> 3) || 3`
+select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3 union select * from v1;
+2 <=> 3 || 3 2 <=> (3 || 3) (2 <=> 3) || 3
+1 0 1
+create or replace view v1 as select 2 <=> 3 XOR 3, 2 <=> (3 XOR 3), (2 <=> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 xor 3 AS `2 <=> 3 XOR 3`,2 <=> (3 xor 3) AS `2 <=> (3 XOR 3)`,2 <=> 3 xor 3 AS `(2 <=> 3) XOR 3`
+select 2 <=> 3 XOR 3, 2 <=> (3 XOR 3), (2 <=> 3) XOR 3 union select * from v1;
+2 <=> 3 XOR 3 2 <=> (3 XOR 3) (2 <=> 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 <=> 2 AND 2, 2 <=> (2 AND 2), (2 <=> 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 2 and 2 AS `2 <=> 2 AND 2`,2 <=> (2 and 2) AS `2 <=> (2 AND 2)`,2 <=> 2 and 2 AS `(2 <=> 2) AND 2`
+select 2 <=> 2 AND 2, 2 <=> (2 AND 2), (2 <=> 2) AND 2 union select * from v1;
+2 <=> 2 AND 2 2 <=> (2 AND 2) (2 <=> 2) AND 2
+1 0 1
+create or replace view v1 as select 2 <=> 2 && 2, 2 <=> (2 && 2), (2 <=> 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 2 and 2 AS `2 <=> 2 && 2`,2 <=> (2 and 2) AS `2 <=> (2 && 2)`,2 <=> 2 and 2 AS `(2 <=> 2) && 2`
+select 2 <=> 2 && 2, 2 <=> (2 && 2), (2 <=> 2) && 2 union select * from v1;
+2 <=> 2 && 2 2 <=> (2 && 2) (2 <=> 2) && 2
+1 0 1
+create or replace view v1 as select 1 <=> 3 = 3, 1 <=> (3 = 3), (1 <=> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 = 3 AS `1 <=> 3 = 3`,1 <=> (3 = 3) AS `1 <=> (3 = 3)`,1 <=> 3 = 3 AS `(1 <=> 3) = 3`
+select 1 <=> 3 = 3, 1 <=> (3 = 3), (1 <=> 3) = 3 union select * from v1;
+1 <=> 3 = 3 1 <=> (3 = 3) (1 <=> 3) = 3
+0 1 0
+create or replace view v1 as select 1 <=> 3 <=> 3, 1 <=> (3 <=> 3), (1 <=> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 <=> 3 AS `1 <=> 3 <=> 3`,1 <=> (3 <=> 3) AS `1 <=> (3 <=> 3)`,1 <=> 3 <=> 3 AS `(1 <=> 3) <=> 3`
+select 1 <=> 3 <=> 3, 1 <=> (3 <=> 3), (1 <=> 3) <=> 3 union select * from v1;
+1 <=> 3 <=> 3 1 <=> (3 <=> 3) (1 <=> 3) <=> 3
+0 1 0
+create or replace view v1 as select 1 <=> 3 >= 3, 1 <=> (3 >= 3), (1 <=> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 >= 3 AS `1 <=> 3 >= 3`,1 <=> (3 >= 3) AS `1 <=> (3 >= 3)`,1 <=> 3 >= 3 AS `(1 <=> 3) >= 3`
+select 1 <=> 3 >= 3, 1 <=> (3 >= 3), (1 <=> 3) >= 3 union select * from v1;
+1 <=> 3 >= 3 1 <=> (3 >= 3) (1 <=> 3) >= 3
+0 1 0
+create or replace view v1 as select 2 <=> 3 <= 3, 2 <=> (3 <= 3), (2 <=> 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 <= 3 AS `2 <=> 3 <= 3`,2 <=> (3 <= 3) AS `2 <=> (3 <= 3)`,2 <=> 3 <= 3 AS `(2 <=> 3) <= 3`
+select 2 <=> 3 <= 3, 2 <=> (3 <= 3), (2 <=> 3) <= 3 union select * from v1;
+2 <=> 3 <= 3 2 <=> (3 <= 3) (2 <=> 3) <= 3
+1 0 1
+create or replace view v1 as select 2 <=> 3 < 3, 2 <=> (3 < 3), (2 <=> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 < 3 AS `2 <=> 3 < 3`,2 <=> (3 < 3) AS `2 <=> (3 < 3)`,2 <=> 3 < 3 AS `(2 <=> 3) < 3`
+select 2 <=> 3 < 3, 2 <=> (3 < 3), (2 <=> 3) < 3 union select * from v1;
+2 <=> 3 < 3 2 <=> (3 < 3) (2 <=> 3) < 3
+1 0 1
+create or replace view v1 as select 2 <=> 3 <> 3, 2 <=> (3 <> 3), (2 <=> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 <> 3 AS `2 <=> 3 <> 3`,2 <=> (3 <> 3) AS `2 <=> (3 <> 3)`,2 <=> 3 <> 3 AS `(2 <=> 3) <> 3`
+select 2 <=> 3 <> 3, 2 <=> (3 <> 3), (2 <=> 3) <> 3 union select * from v1;
+2 <=> 3 <> 3 2 <=> (3 <> 3) (2 <=> 3) <> 3
+1 0 1
+create or replace view v1 as select 0 <=> 3 > 3, 0 <=> (3 > 3), (0 <=> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <=> 3 > 3 AS `0 <=> 3 > 3`,0 <=> (3 > 3) AS `0 <=> (3 > 3)`,0 <=> 3 > 3 AS `(0 <=> 3) > 3`
+select 0 <=> 3 > 3, 0 <=> (3 > 3), (0 <=> 3) > 3 union select * from v1;
+0 <=> 3 > 3 0 <=> (3 > 3) (0 <=> 3) > 3
+0 1 0
+create or replace view v1 as select 2 <=> 3 != 3, 2 <=> (3 != 3), (2 <=> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 <> 3 AS `2 <=> 3 != 3`,2 <=> (3 <> 3) AS `2 <=> (3 != 3)`,2 <=> 3 <> 3 AS `(2 <=> 3) != 3`
+select 2 <=> 3 != 3, 2 <=> (3 != 3), (2 <=> 3) != 3 union select * from v1;
+2 <=> 3 != 3 2 <=> (3 != 3) (2 <=> 3) != 3
+1 0 1
+create or replace view v1 as select 1 <=> 3 LIKE 3, 1 <=> (3 LIKE 3), (1 <=> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 like 3 AS `1 <=> 3 LIKE 3`,1 <=> 3 like 3 AS `1 <=> (3 LIKE 3)`,(1 <=> 3) like 3 AS `(1 <=> 3) LIKE 3`
+select 1 <=> 3 LIKE 3, 1 <=> (3 LIKE 3), (1 <=> 3) LIKE 3 union select * from v1;
+1 <=> 3 LIKE 3 1 <=> (3 LIKE 3) (1 <=> 3) LIKE 3
+1 1 0
+create or replace view v1 as select 1 <=> 3 REGEXP 3, 1 <=> (3 REGEXP 3), (1 <=> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 regexp 3 AS `1 <=> 3 REGEXP 3`,1 <=> 3 regexp 3 AS `1 <=> (3 REGEXP 3)`,(1 <=> 3) regexp 3 AS `(1 <=> 3) REGEXP 3`
+select 1 <=> 3 REGEXP 3, 1 <=> (3 REGEXP 3), (1 <=> 3) REGEXP 3 union select * from v1;
+1 <=> 3 REGEXP 3 1 <=> (3 REGEXP 3) (1 <=> 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 <=> 3 | 3, 2 <=> (3 | 3), (2 <=> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 | 3 AS `2 <=> 3 | 3`,2 <=> 3 | 3 AS `2 <=> (3 | 3)`,(2 <=> 3) | 3 AS `(2 <=> 3) | 3`
+select 2 <=> 3 | 3, 2 <=> (3 | 3), (2 <=> 3) | 3 union select * from v1;
+2 <=> 3 | 3 2 <=> (3 | 3) (2 <=> 3) | 3
+0 0 3
+create or replace view v1 as select 2 <=> 3 & 2, 2 <=> (3 & 2), (2 <=> 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 & 2 AS `2 <=> 3 & 2`,2 <=> 3 & 2 AS `2 <=> (3 & 2)`,(2 <=> 3) & 2 AS `(2 <=> 3) & 2`
+select 2 <=> 3 & 2, 2 <=> (3 & 2), (2 <=> 3) & 2 union select * from v1;
+2 <=> 3 & 2 2 <=> (3 & 2) (2 <=> 3) & 2
+1 1 0
+create or replace view v1 as select 3 <=> 3 << 3, 3 <=> (3 << 3), (3 <=> 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 3 << 3 AS `3 <=> 3 << 3`,3 <=> 3 << 3 AS `3 <=> (3 << 3)`,(3 <=> 3) << 3 AS `(3 <=> 3) << 3`
+select 3 <=> 3 << 3, 3 <=> (3 << 3), (3 <=> 3) << 3 union select * from v1;
+3 <=> 3 << 3 3 <=> (3 << 3) (3 <=> 3) << 3
+0 0 8
+create or replace view v1 as select 1 <=> 3 >> 1, 1 <=> (3 >> 1), (1 <=> 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 >> 1 AS `1 <=> 3 >> 1`,1 <=> 3 >> 1 AS `1 <=> (3 >> 1)`,(1 <=> 3) >> 1 AS `(1 <=> 3) >> 1`
+select 1 <=> 3 >> 1, 1 <=> (3 >> 1), (1 <=> 3) >> 1 union select * from v1;
+1 <=> 3 >> 1 1 <=> (3 >> 1) (1 <=> 3) >> 1
+1 1 0
+create or replace view v1 as select 2 <=> '2000-01-01' +INTERVAL 1 DAY, 2 <=> ('2000-01-01' +INTERVAL 1 DAY), (2 <=> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> '2000-01-01' + interval 1 day AS `2 <=> '2000-01-01' +INTERVAL 1 DAY`,2 <=> '2000-01-01' + interval 1 day AS `2 <=> ('2000-01-01' +INTERVAL 1 DAY)`,(2 <=> '2000-01-01') + interval 1 day AS `(2 <=> '2000-01-01') +INTERVAL 1 DAY`
+select 2 <=> '2000-01-01' +INTERVAL 1 DAY, 2 <=> ('2000-01-01' +INTERVAL 1 DAY), (2 <=> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 <=> '2000-01-01' +INTERVAL 1 DAY 2 <=> ('2000-01-01' +INTERVAL 1 DAY) (2 <=> '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 <=> 3 + 3, 2 <=> (3 + 3), (2 <=> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 + 3 AS `2 <=> 3 + 3`,2 <=> 3 + 3 AS `2 <=> (3 + 3)`,(2 <=> 3) + 3 AS `(2 <=> 3) + 3`
+select 2 <=> 3 + 3, 2 <=> (3 + 3), (2 <=> 3) + 3 union select * from v1;
+2 <=> 3 + 3 2 <=> (3 + 3) (2 <=> 3) + 3
+0 0 3
+create or replace view v1 as select 2 <=> 3 - 3, 2 <=> (3 - 3), (2 <=> 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 - 3 AS `2 <=> 3 - 3`,2 <=> 3 - 3 AS `2 <=> (3 - 3)`,(2 <=> 3) - 3 AS `(2 <=> 3) - 3`
+select 2 <=> 3 - 3, 2 <=> (3 - 3), (2 <=> 3) - 3 union select * from v1;
+2 <=> 3 - 3 2 <=> (3 - 3) (2 <=> 3) - 3
+0 0 -3
+create or replace view v1 as select 3 <=> 3 * 3, 3 <=> (3 * 3), (3 <=> 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 3 * 3 AS `3 <=> 3 * 3`,3 <=> 3 * 3 AS `3 <=> (3 * 3)`,(3 <=> 3) * 3 AS `(3 <=> 3) * 3`
+select 3 <=> 3 * 3, 3 <=> (3 * 3), (3 <=> 3) * 3 union select * from v1;
+3 <=> 3 * 3 3 <=> (3 * 3) (3 <=> 3) * 3
+0 0 3
+create or replace view v1 as select 3 <=> 9 / 3, 3 <=> (9 / 3), (3 <=> 9) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 9 / 3 AS `3 <=> 9 / 3`,3 <=> 9 / 3 AS `3 <=> (9 / 3)`,(3 <=> 9) / 3 AS `(3 <=> 9) / 3`
+select 3 <=> 9 / 3, 3 <=> (9 / 3), (3 <=> 9) / 3 union select * from v1;
+3 <=> 9 / 3 3 <=> (9 / 3) (3 <=> 9) / 3
+1 1 0.0000
+create or replace view v1 as select 3 <=> 9 DIV 3, 3 <=> (9 DIV 3), (3 <=> 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 9 DIV 3 AS `3 <=> 9 DIV 3`,3 <=> 9 DIV 3 AS `3 <=> (9 DIV 3)`,(3 <=> 9) DIV 3 AS `(3 <=> 9) DIV 3`
+select 3 <=> 9 DIV 3, 3 <=> (9 DIV 3), (3 <=> 9) DIV 3 union select * from v1;
+3 <=> 9 DIV 3 3 <=> (9 DIV 3) (3 <=> 9) DIV 3
+1 1 0
+create or replace view v1 as select 3 <=> 3 MOD 3, 3 <=> (3 MOD 3), (3 <=> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 3 MOD 3 AS `3 <=> 3 MOD 3`,3 <=> 3 MOD 3 AS `3 <=> (3 MOD 3)`,(3 <=> 3) MOD 3 AS `(3 <=> 3) MOD 3`
+select 3 <=> 3 MOD 3, 3 <=> (3 MOD 3), (3 <=> 3) MOD 3 union select * from v1;
+3 <=> 3 MOD 3 3 <=> (3 MOD 3) (3 <=> 3) MOD 3
+0 0 1
+create or replace view v1 as select 3 <=> 3 % 3, 3 <=> (3 % 3), (3 <=> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <=> 3 MOD 3 AS `3 <=> 3 % 3`,3 <=> 3 MOD 3 AS `3 <=> (3 % 3)`,(3 <=> 3) MOD 3 AS `(3 <=> 3) % 3`
+select 3 <=> 3 % 3, 3 <=> (3 % 3), (3 <=> 3) % 3 union select * from v1;
+3 <=> 3 % 3 3 <=> (3 % 3) (3 <=> 3) % 3
+0 0 1
+create or replace view v1 as select 2 <=> 3 ^ 3, 2 <=> (3 ^ 3), (2 <=> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 ^ 3 AS `2 <=> 3 ^ 3`,2 <=> 3 ^ 3 AS `2 <=> (3 ^ 3)`,(2 <=> 3) ^ 3 AS `(2 <=> 3) ^ 3`
+select 2 <=> 3 ^ 3, 2 <=> (3 ^ 3), (2 <=> 3) ^ 3 union select * from v1;
+2 <=> 3 ^ 3 2 <=> (3 ^ 3) (2 <=> 3) ^ 3
+0 0 3
+create or replace view v1 as select 1 <=> 3 BETWEEN 1 AND 3, 1 <=> (3 BETWEEN 1 AND 3), (1 <=> 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <=> 3 between 1 and 3 AS `1 <=> 3 BETWEEN 1 AND 3`,1 <=> 3 between 1 and 3 AS `1 <=> (3 BETWEEN 1 AND 3)`,(1 <=> 3) between 1 and 3 AS `(1 <=> 3) BETWEEN 1 AND 3`
+select 1 <=> 3 BETWEEN 1 AND 3, 1 <=> (3 BETWEEN 1 AND 3), (1 <=> 3) BETWEEN 1 AND 3 union select * from v1;
+1 <=> 3 BETWEEN 1 AND 3 1 <=> (3 BETWEEN 1 AND 3) (1 <=> 3) BETWEEN 1 AND 3
+1 1 0
+create or replace view v1 as select 4 >= 3 IS FALSE, 4 >= (3 IS FALSE), (4 >= 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 >= 3 is false AS `4 >= 3 IS FALSE`,4 >= (3 is false) AS `4 >= (3 IS FALSE)`,4 >= 3 is false AS `(4 >= 3) IS FALSE`
+select 4 >= 3 IS FALSE, 4 >= (3 IS FALSE), (4 >= 3) IS FALSE union select * from v1;
+4 >= 3 IS FALSE 4 >= (3 IS FALSE) (4 >= 3) IS FALSE
+0 1 0
+create or replace view v1 as select charset(2 >= 3 COLLATE latin1_bin), charset(2 >= (3 COLLATE latin1_bin)), charset((2 >= 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 >= 3 collate latin1_bin) AS `charset(2 >= 3 COLLATE latin1_bin)`,charset(2 >= 3 collate latin1_bin) AS `charset(2 >= (3 COLLATE latin1_bin))`,charset((2 >= 3) collate latin1_bin) AS `charset((2 >= 3) COLLATE latin1_bin)`
+select charset(2 >= 3 COLLATE latin1_bin), charset(2 >= (3 COLLATE latin1_bin)), charset((2 >= 3) COLLATE latin1_bin) union select * from v1;
+charset(2 >= 3 COLLATE latin1_bin) charset(2 >= (3 COLLATE latin1_bin)) charset((2 >= 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 >= 3 IN (1,1), 2 >= (3 IN (1,1)), (2 >= 3) IN (1,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 in (1,1) AS `2 >= 3 IN (1,1)`,2 >= 3 in (1,1) AS `2 >= (3 IN (1,1))`,(2 >= 3) in (1,1) AS `(2 >= 3) IN (1,1)`
+select 2 >= 3 IN (1,1), 2 >= (3 IN (1,1)), (2 >= 3) IN (1,1) union select * from v1;
+2 >= 3 IN (1,1) 2 >= (3 IN (1,1)) (2 >= 3) IN (1,1)
+1 1 0
+create or replace view v1 as select 2 >= 3 OR 0, 2 >= (3 OR 0), (2 >= 3) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 or 0 AS `2 >= 3 OR 0`,2 >= (3 or 0) AS `2 >= (3 OR 0)`,2 >= 3 or 0 AS `(2 >= 3) OR 0`
+select 2 >= 3 OR 0, 2 >= (3 OR 0), (2 >= 3) OR 0 union select * from v1;
+2 >= 3 OR 0 2 >= (3 OR 0) (2 >= 3) OR 0
+0 1 0
+create or replace view v1 as select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 or 0 AS `2 >= 3 || 0`,2 >= (3 or 0) AS `2 >= (3 || 0)`,2 >= 3 or 0 AS `(2 >= 3) || 0`
+select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0 union select * from v1;
+2 >= 3 || 0 2 >= (3 || 0) (2 >= 3) || 0
+0 1 0
+create or replace view v1 as select 2 >= 3 XOR 0, 2 >= (3 XOR 0), (2 >= 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 xor 0 AS `2 >= 3 XOR 0`,2 >= (3 xor 0) AS `2 >= (3 XOR 0)`,2 >= 3 xor 0 AS `(2 >= 3) XOR 0`
+select 2 >= 3 XOR 0, 2 >= (3 XOR 0), (2 >= 3) XOR 0 union select * from v1;
+2 >= 3 XOR 0 2 >= (3 XOR 0) (2 >= 3) XOR 0
+0 1 0
+create or replace view v1 as select 2 >= 3 AND 3, 2 >= (3 AND 3), (2 >= 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 and 3 AS `2 >= 3 AND 3`,2 >= (3 and 3) AS `2 >= (3 AND 3)`,2 >= 3 and 3 AS `(2 >= 3) AND 3`
+select 2 >= 3 AND 3, 2 >= (3 AND 3), (2 >= 3) AND 3 union select * from v1;
+2 >= 3 AND 3 2 >= (3 AND 3) (2 >= 3) AND 3
+0 1 0
+create or replace view v1 as select 2 >= 3 && 3, 2 >= (3 && 3), (2 >= 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 and 3 AS `2 >= 3 && 3`,2 >= (3 and 3) AS `2 >= (3 && 3)`,2 >= 3 and 3 AS `(2 >= 3) && 3`
+select 2 >= 3 && 3, 2 >= (3 && 3), (2 >= 3) && 3 union select * from v1;
+2 >= 3 && 3 2 >= (3 && 3) (2 >= 3) && 3
+0 1 0
+create or replace view v1 as select 2 >= 3 = 3, 2 >= (3 = 3), (2 >= 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 = 3 AS `2 >= 3 = 3`,2 >= (3 = 3) AS `2 >= (3 = 3)`,2 >= 3 = 3 AS `(2 >= 3) = 3`
+select 2 >= 3 = 3, 2 >= (3 = 3), (2 >= 3) = 3 union select * from v1;
+2 >= 3 = 3 2 >= (3 = 3) (2 >= 3) = 3
+0 1 0
+create or replace view v1 as select 2 >= 3 <=> 3, 2 >= (3 <=> 3), (2 >= 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 <=> 3 AS `2 >= 3 <=> 3`,2 >= (3 <=> 3) AS `2 >= (3 <=> 3)`,2 >= 3 <=> 3 AS `(2 >= 3) <=> 3`
+select 2 >= 3 <=> 3, 2 >= (3 <=> 3), (2 >= 3) <=> 3 union select * from v1;
+2 >= 3 <=> 3 2 >= (3 <=> 3) (2 >= 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 >= 3 >= 3, 2 >= (3 >= 3), (2 >= 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 >= 3 AS `2 >= 3 >= 3`,2 >= (3 >= 3) AS `2 >= (3 >= 3)`,2 >= 3 >= 3 AS `(2 >= 3) >= 3`
+select 2 >= 3 >= 3, 2 >= (3 >= 3), (2 >= 3) >= 3 union select * from v1;
+2 >= 3 >= 3 2 >= (3 >= 3) (2 >= 3) >= 3
+0 1 0
+create or replace view v1 as select 0 >= 3 <= 3, 0 >= (3 <= 3), (0 >= 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 >= 3 <= 3 AS `0 >= 3 <= 3`,0 >= (3 <= 3) AS `0 >= (3 <= 3)`,0 >= 3 <= 3 AS `(0 >= 3) <= 3`
+select 0 >= 3 <= 3, 0 >= (3 <= 3), (0 >= 3) <= 3 union select * from v1;
+0 >= 3 <= 3 0 >= (3 <= 3) (0 >= 3) <= 3
+1 0 1
+create or replace view v1 as select 0 >= 2 < 3, 0 >= (2 < 3), (0 >= 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 >= 2 < 3 AS `0 >= 2 < 3`,0 >= (2 < 3) AS `0 >= (2 < 3)`,0 >= 2 < 3 AS `(0 >= 2) < 3`
+select 0 >= 2 < 3, 0 >= (2 < 3), (0 >= 2) < 3 union select * from v1;
+0 >= 2 < 3 0 >= (2 < 3) (0 >= 2) < 3
+1 0 1
+create or replace view v1 as select 2 >= 3 <> 0, 2 >= (3 <> 0), (2 >= 3) <> 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 <> 0 AS `2 >= 3 <> 0`,2 >= (3 <> 0) AS `2 >= (3 <> 0)`,2 >= 3 <> 0 AS `(2 >= 3) <> 0`
+select 2 >= 3 <> 0, 2 >= (3 <> 0), (2 >= 3) <> 0 union select * from v1;
+2 >= 3 <> 0 2 >= (3 <> 0) (2 >= 3) <> 0
+0 1 0
+create or replace view v1 as select 2 >= 3 > 3, 2 >= (3 > 3), (2 >= 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 > 3 AS `2 >= 3 > 3`,2 >= (3 > 3) AS `2 >= (3 > 3)`,2 >= 3 > 3 AS `(2 >= 3) > 3`
+select 2 >= 3 > 3, 2 >= (3 > 3), (2 >= 3) > 3 union select * from v1;
+2 >= 3 > 3 2 >= (3 > 3) (2 >= 3) > 3
+0 1 0
+create or replace view v1 as select 2 >= 3 != 0, 2 >= (3 != 0), (2 >= 3) != 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 <> 0 AS `2 >= 3 != 0`,2 >= (3 <> 0) AS `2 >= (3 != 0)`,2 >= 3 <> 0 AS `(2 >= 3) != 0`
+select 2 >= 3 != 0, 2 >= (3 != 0), (2 >= 3) != 0 union select * from v1;
+2 >= 3 != 0 2 >= (3 != 0) (2 >= 3) != 0
+0 1 0
+create or replace view v1 as select 2 >= 3 LIKE 3, 2 >= (3 LIKE 3), (2 >= 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 like 3 AS `2 >= 3 LIKE 3`,2 >= 3 like 3 AS `2 >= (3 LIKE 3)`,(2 >= 3) like 3 AS `(2 >= 3) LIKE 3`
+select 2 >= 3 LIKE 3, 2 >= (3 LIKE 3), (2 >= 3) LIKE 3 union select * from v1;
+2 >= 3 LIKE 3 2 >= (3 LIKE 3) (2 >= 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 >= 3 REGEXP 3, 2 >= (3 REGEXP 3), (2 >= 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 regexp 3 AS `2 >= 3 REGEXP 3`,2 >= 3 regexp 3 AS `2 >= (3 REGEXP 3)`,(2 >= 3) regexp 3 AS `(2 >= 3) REGEXP 3`
+select 2 >= 3 REGEXP 3, 2 >= (3 REGEXP 3), (2 >= 3) REGEXP 3 union select * from v1;
+2 >= 3 REGEXP 3 2 >= (3 REGEXP 3) (2 >= 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 >= 3 | 3, 2 >= (3 | 3), (2 >= 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 | 3 AS `2 >= 3 | 3`,2 >= 3 | 3 AS `2 >= (3 | 3)`,(2 >= 3) | 3 AS `(2 >= 3) | 3`
+select 2 >= 3 | 3, 2 >= (3 | 3), (2 >= 3) | 3 union select * from v1;
+2 >= 3 | 3 2 >= (3 | 3) (2 >= 3) | 3
+0 0 3
+create or replace view v1 as select 2 >= 3 & 1, 2 >= (3 & 1), (2 >= 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 & 1 AS `2 >= 3 & 1`,2 >= 3 & 1 AS `2 >= (3 & 1)`,(2 >= 3) & 1 AS `(2 >= 3) & 1`
+select 2 >= 3 & 1, 2 >= (3 & 1), (2 >= 3) & 1 union select * from v1;
+2 >= 3 & 1 2 >= (3 & 1) (2 >= 3) & 1
+1 1 0
+create or replace view v1 as select 3 >= 3 << 3, 3 >= (3 << 3), (3 >= 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 >= 3 << 3 AS `3 >= 3 << 3`,3 >= 3 << 3 AS `3 >= (3 << 3)`,(3 >= 3) << 3 AS `(3 >= 3) << 3`
+select 3 >= 3 << 3, 3 >= (3 << 3), (3 >= 3) << 3 union select * from v1;
+3 >= 3 << 3 3 >= (3 << 3) (3 >= 3) << 3
+0 0 8
+create or replace view v1 as select 2 >= 3 >> 3, 2 >= (3 >> 3), (2 >= 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 >> 3 AS `2 >= 3 >> 3`,2 >= 3 >> 3 AS `2 >= (3 >> 3)`,(2 >= 3) >> 3 AS `(2 >= 3) >> 3`
+select 2 >= 3 >> 3, 2 >= (3 >> 3), (2 >= 3) >> 3 union select * from v1;
+2 >= 3 >> 3 2 >= (3 >> 3) (2 >= 3) >> 3
+1 1 0
+create or replace view v1 as select 2 >= '2000-01-01' +INTERVAL 1 DAY, 2 >= ('2000-01-01' +INTERVAL 1 DAY), (2 >= '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= '2000-01-01' + interval 1 day AS `2 >= '2000-01-01' +INTERVAL 1 DAY`,2 >= '2000-01-01' + interval 1 day AS `2 >= ('2000-01-01' +INTERVAL 1 DAY)`,(2 >= '2000-01-01') + interval 1 day AS `(2 >= '2000-01-01') +INTERVAL 1 DAY`
+select 2 >= '2000-01-01' +INTERVAL 1 DAY, 2 >= ('2000-01-01' +INTERVAL 1 DAY), (2 >= '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 >= '2000-01-01' +INTERVAL 1 DAY 2 >= ('2000-01-01' +INTERVAL 1 DAY) (2 >= '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 >= 3 + 3, 2 >= (3 + 3), (2 >= 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 + 3 AS `2 >= 3 + 3`,2 >= 3 + 3 AS `2 >= (3 + 3)`,(2 >= 3) + 3 AS `(2 >= 3) + 3`
+select 2 >= 3 + 3, 2 >= (3 + 3), (2 >= 3) + 3 union select * from v1;
+2 >= 3 + 3 2 >= (3 + 3) (2 >= 3) + 3
+0 0 3
+create or replace view v1 as select 2 >= 3 - 3, 2 >= (3 - 3), (2 >= 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 - 3 AS `2 >= 3 - 3`,2 >= 3 - 3 AS `2 >= (3 - 3)`,(2 >= 3) - 3 AS `(2 >= 3) - 3`
+select 2 >= 3 - 3, 2 >= (3 - 3), (2 >= 3) - 3 union select * from v1;
+2 >= 3 - 3 2 >= (3 - 3) (2 >= 3) - 3
+1 1 -3
+create or replace view v1 as select 3 >= 3 * 3, 3 >= (3 * 3), (3 >= 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 >= 3 * 3 AS `3 >= 3 * 3`,3 >= 3 * 3 AS `3 >= (3 * 3)`,(3 >= 3) * 3 AS `(3 >= 3) * 3`
+select 3 >= 3 * 3, 3 >= (3 * 3), (3 >= 3) * 3 union select * from v1;
+3 >= 3 * 3 3 >= (3 * 3) (3 >= 3) * 3
+0 0 3
+create or replace view v1 as select 2 >= 3 / 3, 2 >= (3 / 3), (2 >= 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 / 3 AS `2 >= 3 / 3`,2 >= 3 / 3 AS `2 >= (3 / 3)`,(2 >= 3) / 3 AS `(2 >= 3) / 3`
+select 2 >= 3 / 3, 2 >= (3 / 3), (2 >= 3) / 3 union select * from v1;
+2 >= 3 / 3 2 >= (3 / 3) (2 >= 3) / 3
+1 1 0.0000
+create or replace view v1 as select 2 >= 3 DIV 3, 2 >= (3 DIV 3), (2 >= 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 DIV 3 AS `2 >= 3 DIV 3`,2 >= 3 DIV 3 AS `2 >= (3 DIV 3)`,(2 >= 3) DIV 3 AS `(2 >= 3) DIV 3`
+select 2 >= 3 DIV 3, 2 >= (3 DIV 3), (2 >= 3) DIV 3 union select * from v1;
+2 >= 3 DIV 3 2 >= (3 DIV 3) (2 >= 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 >= 3 MOD 3, 2 >= (3 MOD 3), (2 >= 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 MOD 3 AS `2 >= 3 MOD 3`,2 >= 3 MOD 3 AS `2 >= (3 MOD 3)`,(2 >= 3) MOD 3 AS `(2 >= 3) MOD 3`
+select 2 >= 3 MOD 3, 2 >= (3 MOD 3), (2 >= 3) MOD 3 union select * from v1;
+2 >= 3 MOD 3 2 >= (3 MOD 3) (2 >= 3) MOD 3
+1 1 0
+create or replace view v1 as select 2 >= 3 % 3, 2 >= (3 % 3), (2 >= 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 MOD 3 AS `2 >= 3 % 3`,2 >= 3 MOD 3 AS `2 >= (3 % 3)`,(2 >= 3) MOD 3 AS `(2 >= 3) % 3`
+select 2 >= 3 % 3, 2 >= (3 % 3), (2 >= 3) % 3 union select * from v1;
+2 >= 3 % 3 2 >= (3 % 3) (2 >= 3) % 3
+1 1 0
+create or replace view v1 as select 2 >= 3 ^ 3, 2 >= (3 ^ 3), (2 >= 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 ^ 3 AS `2 >= 3 ^ 3`,2 >= 3 ^ 3 AS `2 >= (3 ^ 3)`,(2 >= 3) ^ 3 AS `(2 >= 3) ^ 3`
+select 2 >= 3 ^ 3, 2 >= (3 ^ 3), (2 >= 3) ^ 3 union select * from v1;
+2 >= 3 ^ 3 2 >= (3 ^ 3) (2 >= 3) ^ 3
+1 1 3
+create or replace view v1 as select 2 >= 3 BETWEEN 1 AND 3, 2 >= (3 BETWEEN 1 AND 3), (2 >= 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 between 1 and 3 AS `2 >= 3 BETWEEN 1 AND 3`,2 >= 3 between 1 and 3 AS `2 >= (3 BETWEEN 1 AND 3)`,(2 >= 3) between 1 and 3 AS `(2 >= 3) BETWEEN 1 AND 3`
+select 2 >= 3 BETWEEN 1 AND 3, 2 >= (3 BETWEEN 1 AND 3), (2 >= 3) BETWEEN 1 AND 3 union select * from v1;
+2 >= 3 BETWEEN 1 AND 3 2 >= (3 BETWEEN 1 AND 3) (2 >= 3) BETWEEN 1 AND 3
+1 1 0
+create or replace view v1 as select 2 <= 1 IS FALSE, 2 <= (1 IS FALSE), (2 <= 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 1 is false AS `2 <= 1 IS FALSE`,2 <= (1 is false) AS `2 <= (1 IS FALSE)`,2 <= 1 is false AS `(2 <= 1) IS FALSE`
+select 2 <= 1 IS FALSE, 2 <= (1 IS FALSE), (2 <= 1) IS FALSE union select * from v1;
+2 <= 1 IS FALSE 2 <= (1 IS FALSE) (2 <= 1) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 <= 3 COLLATE latin1_bin), charset(2 <= (3 COLLATE latin1_bin)), charset((2 <= 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 <= 3 collate latin1_bin) AS `charset(2 <= 3 COLLATE latin1_bin)`,charset(2 <= 3 collate latin1_bin) AS `charset(2 <= (3 COLLATE latin1_bin))`,charset((2 <= 3) collate latin1_bin) AS `charset((2 <= 3) COLLATE latin1_bin)`
+select charset(2 <= 3 COLLATE latin1_bin), charset(2 <= (3 COLLATE latin1_bin)), charset((2 <= 3) COLLATE latin1_bin) union select * from v1;
+charset(2 <= 3 COLLATE latin1_bin) charset(2 <= (3 COLLATE latin1_bin)) charset((2 <= 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 <= 3 IN (0,1), 2 <= (3 IN (0,1)), (2 <= 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 in (0,1) AS `2 <= 3 IN (0,1)`,2 <= 3 in (0,1) AS `2 <= (3 IN (0,1))`,(2 <= 3) in (0,1) AS `(2 <= 3) IN (0,1)`
+select 2 <= 3 IN (0,1), 2 <= (3 IN (0,1)), (2 <= 3) IN (0,1) union select * from v1;
+2 <= 3 IN (0,1) 2 <= (3 IN (0,1)) (2 <= 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 2 <= 3 OR 3, 2 <= (3 OR 3), (2 <= 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 or 3 AS `2 <= 3 OR 3`,2 <= (3 or 3) AS `2 <= (3 OR 3)`,2 <= 3 or 3 AS `(2 <= 3) OR 3`
+select 2 <= 3 OR 3, 2 <= (3 OR 3), (2 <= 3) OR 3 union select * from v1;
+2 <= 3 OR 3 2 <= (3 OR 3) (2 <= 3) OR 3
+1 0 1
+create or replace view v1 as select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 or 3 AS `2 <= 3 || 3`,2 <= (3 or 3) AS `2 <= (3 || 3)`,2 <= 3 or 3 AS `(2 <= 3) || 3`
+select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3 union select * from v1;
+2 <= 3 || 3 2 <= (3 || 3) (2 <= 3) || 3
+1 0 1
+create or replace view v1 as select 2 <= 1 XOR 1, 2 <= (1 XOR 1), (2 <= 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 1 xor 1 AS `2 <= 1 XOR 1`,2 <= (1 xor 1) AS `2 <= (1 XOR 1)`,2 <= 1 xor 1 AS `(2 <= 1) XOR 1`
+select 2 <= 1 XOR 1, 2 <= (1 XOR 1), (2 <= 1) XOR 1 union select * from v1;
+2 <= 1 XOR 1 2 <= (1 XOR 1) (2 <= 1) XOR 1
+1 0 1
+create or replace view v1 as select 2 <= 3 AND 3, 2 <= (3 AND 3), (2 <= 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 and 3 AS `2 <= 3 AND 3`,2 <= (3 and 3) AS `2 <= (3 AND 3)`,2 <= 3 and 3 AS `(2 <= 3) AND 3`
+select 2 <= 3 AND 3, 2 <= (3 AND 3), (2 <= 3) AND 3 union select * from v1;
+2 <= 3 AND 3 2 <= (3 AND 3) (2 <= 3) AND 3
+1 0 1
+create or replace view v1 as select 2 <= 3 && 3, 2 <= (3 && 3), (2 <= 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 and 3 AS `2 <= 3 && 3`,2 <= (3 and 3) AS `2 <= (3 && 3)`,2 <= 3 and 3 AS `(2 <= 3) && 3`
+select 2 <= 3 && 3, 2 <= (3 && 3), (2 <= 3) && 3 union select * from v1;
+2 <= 3 && 3 2 <= (3 && 3) (2 <= 3) && 3
+1 0 1
+create or replace view v1 as select 2 <= 0 = 0, 2 <= (0 = 0), (2 <= 0) = 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 0 = 0 AS `2 <= 0 = 0`,2 <= (0 = 0) AS `2 <= (0 = 0)`,2 <= 0 = 0 AS `(2 <= 0) = 0`
+select 2 <= 0 = 0, 2 <= (0 = 0), (2 <= 0) = 0 union select * from v1;
+2 <= 0 = 0 2 <= (0 = 0) (2 <= 0) = 0
+1 0 1
+create or replace view v1 as select 2 <= 0 <=> 0, 2 <= (0 <=> 0), (2 <= 0) <=> 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 0 <=> 0 AS `2 <= 0 <=> 0`,2 <= (0 <=> 0) AS `2 <= (0 <=> 0)`,2 <= 0 <=> 0 AS `(2 <= 0) <=> 0`
+select 2 <= 0 <=> 0, 2 <= (0 <=> 0), (2 <= 0) <=> 0 union select * from v1;
+2 <= 0 <=> 0 2 <= (0 <=> 0) (2 <= 0) <=> 0
+1 0 1
+create or replace view v1 as select 2 <= 0 >= 0, 2 <= (0 >= 0), (2 <= 0) >= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 0 >= 0 AS `2 <= 0 >= 0`,2 <= (0 >= 0) AS `2 <= (0 >= 0)`,2 <= 0 >= 0 AS `(2 <= 0) >= 0`
+select 2 <= 0 >= 0, 2 <= (0 >= 0), (2 <= 0) >= 0 union select * from v1;
+2 <= 0 >= 0 2 <= (0 >= 0) (2 <= 0) >= 0
+1 0 1
+create or replace view v1 as select 2 <= 3 <= 3, 2 <= (3 <= 3), (2 <= 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 <= 3 AS `2 <= 3 <= 3`,2 <= (3 <= 3) AS `2 <= (3 <= 3)`,2 <= 3 <= 3 AS `(2 <= 3) <= 3`
+select 2 <= 3 <= 3, 2 <= (3 <= 3), (2 <= 3) <= 3 union select * from v1;
+2 <= 3 <= 3 2 <= (3 <= 3) (2 <= 3) <= 3
+1 0 1
+create or replace view v1 as select 2 <= 3 < 3, 2 <= (3 < 3), (2 <= 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 < 3 AS `2 <= 3 < 3`,2 <= (3 < 3) AS `2 <= (3 < 3)`,2 <= 3 < 3 AS `(2 <= 3) < 3`
+select 2 <= 3 < 3, 2 <= (3 < 3), (2 <= 3) < 3 union select * from v1;
+2 <= 3 < 3 2 <= (3 < 3) (2 <= 3) < 3
+1 0 1
+create or replace view v1 as select 2 <= 3 <> 3, 2 <= (3 <> 3), (2 <= 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 <> 3 AS `2 <= 3 <> 3`,2 <= (3 <> 3) AS `2 <= (3 <> 3)`,2 <= 3 <> 3 AS `(2 <= 3) <> 3`
+select 2 <= 3 <> 3, 2 <= (3 <> 3), (2 <= 3) <> 3 union select * from v1;
+2 <= 3 <> 3 2 <= (3 <> 3) (2 <= 3) <> 3
+1 0 1
+create or replace view v1 as select 2 <= 3 > 0, 2 <= (3 > 0), (2 <= 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 > 0 AS `2 <= 3 > 0`,2 <= (3 > 0) AS `2 <= (3 > 0)`,2 <= 3 > 0 AS `(2 <= 3) > 0`
+select 2 <= 3 > 0, 2 <= (3 > 0), (2 <= 3) > 0 union select * from v1;
+2 <= 3 > 0 2 <= (3 > 0) (2 <= 3) > 0
+1 0 1
+create or replace view v1 as select 2 <= 3 != 3, 2 <= (3 != 3), (2 <= 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 <> 3 AS `2 <= 3 != 3`,2 <= (3 <> 3) AS `2 <= (3 != 3)`,2 <= 3 <> 3 AS `(2 <= 3) != 3`
+select 2 <= 3 != 3, 2 <= (3 != 3), (2 <= 3) != 3 union select * from v1;
+2 <= 3 != 3 2 <= (3 != 3) (2 <= 3) != 3
+1 0 1
+create or replace view v1 as select 2 <= 0 LIKE 0, 2 <= (0 LIKE 0), (2 <= 0) LIKE 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 0 like 0 AS `2 <= 0 LIKE 0`,2 <= 0 like 0 AS `2 <= (0 LIKE 0)`,(2 <= 0) like 0 AS `(2 <= 0) LIKE 0`
+select 2 <= 0 LIKE 0, 2 <= (0 LIKE 0), (2 <= 0) LIKE 0 union select * from v1;
+2 <= 0 LIKE 0 2 <= (0 LIKE 0) (2 <= 0) LIKE 0
+0 0 1
+create or replace view v1 as select 2 <= 0 REGEXP 0, 2 <= (0 REGEXP 0), (2 <= 0) REGEXP 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 0 regexp 0 AS `2 <= 0 REGEXP 0`,2 <= 0 regexp 0 AS `2 <= (0 REGEXP 0)`,(2 <= 0) regexp 0 AS `(2 <= 0) REGEXP 0`
+select 2 <= 0 REGEXP 0, 2 <= (0 REGEXP 0), (2 <= 0) REGEXP 0 union select * from v1;
+2 <= 0 REGEXP 0 2 <= (0 REGEXP 0) (2 <= 0) REGEXP 0
+0 0 1
+create or replace view v1 as select 2 <= 3 | 3, 2 <= (3 | 3), (2 <= 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 | 3 AS `2 <= 3 | 3`,2 <= 3 | 3 AS `2 <= (3 | 3)`,(2 <= 3) | 3 AS `(2 <= 3) | 3`
+select 2 <= 3 | 3, 2 <= (3 | 3), (2 <= 3) | 3 union select * from v1;
+2 <= 3 | 3 2 <= (3 | 3) (2 <= 3) | 3
+1 1 3
+create or replace view v1 as select 2 <= 3 & 2, 2 <= (3 & 2), (2 <= 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 & 2 AS `2 <= 3 & 2`,2 <= 3 & 2 AS `2 <= (3 & 2)`,(2 <= 3) & 2 AS `(2 <= 3) & 2`
+select 2 <= 3 & 2, 2 <= (3 & 2), (2 <= 3) & 2 union select * from v1;
+2 <= 3 & 2 2 <= (3 & 2) (2 <= 3) & 2
+1 1 0
+create or replace view v1 as select 2 <= 3 << 3, 2 <= (3 << 3), (2 <= 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 << 3 AS `2 <= 3 << 3`,2 <= 3 << 3 AS `2 <= (3 << 3)`,(2 <= 3) << 3 AS `(2 <= 3) << 3`
+select 2 <= 3 << 3, 2 <= (3 << 3), (2 <= 3) << 3 union select * from v1;
+2 <= 3 << 3 2 <= (3 << 3) (2 <= 3) << 3
+1 1 8
+create or replace view v1 as select 0 <= 3 >> 1, 0 <= (3 >> 1), (0 <= 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <= 3 >> 1 AS `0 <= 3 >> 1`,0 <= 3 >> 1 AS `0 <= (3 >> 1)`,(0 <= 3) >> 1 AS `(0 <= 3) >> 1`
+select 0 <= 3 >> 1, 0 <= (3 >> 1), (0 <= 3) >> 1 union select * from v1;
+0 <= 3 >> 1 0 <= (3 >> 1) (0 <= 3) >> 1
+1 1 0
+create or replace view v1 as select 2 <= '2000-01-01' +INTERVAL 1 DAY, 2 <= ('2000-01-01' +INTERVAL 1 DAY), (2 <= '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= '2000-01-01' + interval 1 day AS `2 <= '2000-01-01' +INTERVAL 1 DAY`,2 <= '2000-01-01' + interval 1 day AS `2 <= ('2000-01-01' +INTERVAL 1 DAY)`,(2 <= '2000-01-01') + interval 1 day AS `(2 <= '2000-01-01') +INTERVAL 1 DAY`
+select 2 <= '2000-01-01' +INTERVAL 1 DAY, 2 <= ('2000-01-01' +INTERVAL 1 DAY), (2 <= '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 <= '2000-01-01' +INTERVAL 1 DAY 2 <= ('2000-01-01' +INTERVAL 1 DAY) (2 <= '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 <= 3 + 3, 2 <= (3 + 3), (2 <= 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 + 3 AS `2 <= 3 + 3`,2 <= 3 + 3 AS `2 <= (3 + 3)`,(2 <= 3) + 3 AS `(2 <= 3) + 3`
+select 2 <= 3 + 3, 2 <= (3 + 3), (2 <= 3) + 3 union select * from v1;
+2 <= 3 + 3 2 <= (3 + 3) (2 <= 3) + 3
+1 1 4
+create or replace view v1 as select 2 <= 3 - 3, 2 <= (3 - 3), (2 <= 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 - 3 AS `2 <= 3 - 3`,2 <= 3 - 3 AS `2 <= (3 - 3)`,(2 <= 3) - 3 AS `(2 <= 3) - 3`
+select 2 <= 3 - 3, 2 <= (3 - 3), (2 <= 3) - 3 union select * from v1;
+2 <= 3 - 3 2 <= (3 - 3) (2 <= 3) - 3
+0 0 -2
+create or replace view v1 as select 2 <= 3 * 3, 2 <= (3 * 3), (2 <= 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 * 3 AS `2 <= 3 * 3`,2 <= 3 * 3 AS `2 <= (3 * 3)`,(2 <= 3) * 3 AS `(2 <= 3) * 3`
+select 2 <= 3 * 3, 2 <= (3 * 3), (2 <= 3) * 3 union select * from v1;
+2 <= 3 * 3 2 <= (3 * 3) (2 <= 3) * 3
+1 1 3
+create or replace view v1 as select 2 <= 3 / 3, 2 <= (3 / 3), (2 <= 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 / 3 AS `2 <= 3 / 3`,2 <= 3 / 3 AS `2 <= (3 / 3)`,(2 <= 3) / 3 AS `(2 <= 3) / 3`
+select 2 <= 3 / 3, 2 <= (3 / 3), (2 <= 3) / 3 union select * from v1;
+2 <= 3 / 3 2 <= (3 / 3) (2 <= 3) / 3
+0 0 0.3333
+create or replace view v1 as select 2 <= 9 DIV 3, 2 <= (9 DIV 3), (2 <= 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 9 DIV 3 AS `2 <= 9 DIV 3`,2 <= 9 DIV 3 AS `2 <= (9 DIV 3)`,(2 <= 9) DIV 3 AS `(2 <= 9) DIV 3`
+select 2 <= 9 DIV 3, 2 <= (9 DIV 3), (2 <= 9) DIV 3 union select * from v1;
+2 <= 9 DIV 3 2 <= (9 DIV 3) (2 <= 9) DIV 3
+1 1 0
+create or replace view v1 as select 2 <= 3 MOD 3, 2 <= (3 MOD 3), (2 <= 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 MOD 3 AS `2 <= 3 MOD 3`,2 <= 3 MOD 3 AS `2 <= (3 MOD 3)`,(2 <= 3) MOD 3 AS `(2 <= 3) MOD 3`
+select 2 <= 3 MOD 3, 2 <= (3 MOD 3), (2 <= 3) MOD 3 union select * from v1;
+2 <= 3 MOD 3 2 <= (3 MOD 3) (2 <= 3) MOD 3
+0 0 1
+create or replace view v1 as select 2 <= 3 % 3, 2 <= (3 % 3), (2 <= 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 MOD 3 AS `2 <= 3 % 3`,2 <= 3 MOD 3 AS `2 <= (3 % 3)`,(2 <= 3) MOD 3 AS `(2 <= 3) % 3`
+select 2 <= 3 % 3, 2 <= (3 % 3), (2 <= 3) % 3 union select * from v1;
+2 <= 3 % 3 2 <= (3 % 3) (2 <= 3) % 3
+0 0 1
+create or replace view v1 as select 2 <= 3 ^ 3, 2 <= (3 ^ 3), (2 <= 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 ^ 3 AS `2 <= 3 ^ 3`,2 <= 3 ^ 3 AS `2 <= (3 ^ 3)`,(2 <= 3) ^ 3 AS `(2 <= 3) ^ 3`
+select 2 <= 3 ^ 3, 2 <= (3 ^ 3), (2 <= 3) ^ 3 union select * from v1;
+2 <= 3 ^ 3 2 <= (3 ^ 3) (2 <= 3) ^ 3
+0 0 2
+create or replace view v1 as select 2 <= 3 BETWEEN 1 AND 3, 2 <= (3 BETWEEN 1 AND 3), (2 <= 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 between 1 and 3 AS `2 <= 3 BETWEEN 1 AND 3`,2 <= 3 between 1 and 3 AS `2 <= (3 BETWEEN 1 AND 3)`,(2 <= 3) between 1 and 3 AS `(2 <= 3) BETWEEN 1 AND 3`
+select 2 <= 3 BETWEEN 1 AND 3, 2 <= (3 BETWEEN 1 AND 3), (2 <= 3) BETWEEN 1 AND 3 union select * from v1;
+2 <= 3 BETWEEN 1 AND 3 2 <= (3 BETWEEN 1 AND 3) (2 <= 3) BETWEEN 1 AND 3
+0 0 1
+create or replace view v1 as select 2 < 1 IS FALSE, 2 < (1 IS FALSE), (2 < 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 1 is false AS `2 < 1 IS FALSE`,2 < (1 is false) AS `2 < (1 IS FALSE)`,2 < 1 is false AS `(2 < 1) IS FALSE`
+select 2 < 1 IS FALSE, 2 < (1 IS FALSE), (2 < 1) IS FALSE union select * from v1;
+2 < 1 IS FALSE 2 < (1 IS FALSE) (2 < 1) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 < 3 COLLATE latin1_bin), charset(2 < (3 COLLATE latin1_bin)), charset((2 < 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 < 3 collate latin1_bin) AS `charset(2 < 3 COLLATE latin1_bin)`,charset(2 < 3 collate latin1_bin) AS `charset(2 < (3 COLLATE latin1_bin))`,charset((2 < 3) collate latin1_bin) AS `charset((2 < 3) COLLATE latin1_bin)`
+select charset(2 < 3 COLLATE latin1_bin), charset(2 < (3 COLLATE latin1_bin)), charset((2 < 3) COLLATE latin1_bin) union select * from v1;
+charset(2 < 3 COLLATE latin1_bin) charset(2 < (3 COLLATE latin1_bin)) charset((2 < 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 < 3 IN (0,1), 2 < (3 IN (0,1)), (2 < 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 in (0,1) AS `2 < 3 IN (0,1)`,2 < 3 in (0,1) AS `2 < (3 IN (0,1))`,(2 < 3) in (0,1) AS `(2 < 3) IN (0,1)`
+select 2 < 3 IN (0,1), 2 < (3 IN (0,1)), (2 < 3) IN (0,1) union select * from v1;
+2 < 3 IN (0,1) 2 < (3 IN (0,1)) (2 < 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 2 < 3 OR 3, 2 < (3 OR 3), (2 < 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 or 3 AS `2 < 3 OR 3`,2 < (3 or 3) AS `2 < (3 OR 3)`,2 < 3 or 3 AS `(2 < 3) OR 3`
+select 2 < 3 OR 3, 2 < (3 OR 3), (2 < 3) OR 3 union select * from v1;
+2 < 3 OR 3 2 < (3 OR 3) (2 < 3) OR 3
+1 0 1
+create or replace view v1 as select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 or 3 AS `2 < 3 || 3`,2 < (3 or 3) AS `2 < (3 || 3)`,2 < 3 or 3 AS `(2 < 3) || 3`
+select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3 union select * from v1;
+2 < 3 || 3 2 < (3 || 3) (2 < 3) || 3
+1 0 1
+create or replace view v1 as select 2 < 3 XOR 0, 2 < (3 XOR 0), (2 < 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 xor 0 AS `2 < 3 XOR 0`,2 < (3 xor 0) AS `2 < (3 XOR 0)`,2 < 3 xor 0 AS `(2 < 3) XOR 0`
+select 2 < 3 XOR 0, 2 < (3 XOR 0), (2 < 3) XOR 0 union select * from v1;
+2 < 3 XOR 0 2 < (3 XOR 0) (2 < 3) XOR 0
+1 0 1
+create or replace view v1 as select 2 < 3 AND 3, 2 < (3 AND 3), (2 < 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 and 3 AS `2 < 3 AND 3`,2 < (3 and 3) AS `2 < (3 AND 3)`,2 < 3 and 3 AS `(2 < 3) AND 3`
+select 2 < 3 AND 3, 2 < (3 AND 3), (2 < 3) AND 3 union select * from v1;
+2 < 3 AND 3 2 < (3 AND 3) (2 < 3) AND 3
+1 0 1
+create or replace view v1 as select 2 < 3 && 3, 2 < (3 && 3), (2 < 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 and 3 AS `2 < 3 && 3`,2 < (3 and 3) AS `2 < (3 && 3)`,2 < 3 and 3 AS `(2 < 3) && 3`
+select 2 < 3 && 3, 2 < (3 && 3), (2 < 3) && 3 union select * from v1;
+2 < 3 && 3 2 < (3 && 3) (2 < 3) && 3
+1 0 1
+create or replace view v1 as select 2 < 3 = 1, 2 < (3 = 1), (2 < 3) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 = 1 AS `2 < 3 = 1`,2 < (3 = 1) AS `2 < (3 = 1)`,2 < 3 = 1 AS `(2 < 3) = 1`
+select 2 < 3 = 1, 2 < (3 = 1), (2 < 3) = 1 union select * from v1;
+2 < 3 = 1 2 < (3 = 1) (2 < 3) = 1
+1 0 1
+create or replace view v1 as select 2 < 3 <=> 1, 2 < (3 <=> 1), (2 < 3) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 <=> 1 AS `2 < 3 <=> 1`,2 < (3 <=> 1) AS `2 < (3 <=> 1)`,2 < 3 <=> 1 AS `(2 < 3) <=> 1`
+select 2 < 3 <=> 1, 2 < (3 <=> 1), (2 < 3) <=> 1 union select * from v1;
+2 < 3 <=> 1 2 < (3 <=> 1) (2 < 3) <=> 1
+1 0 1
+create or replace view v1 as select 2 < 3 >= 1, 2 < (3 >= 1), (2 < 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 >= 1 AS `2 < 3 >= 1`,2 < (3 >= 1) AS `2 < (3 >= 1)`,2 < 3 >= 1 AS `(2 < 3) >= 1`
+select 2 < 3 >= 1, 2 < (3 >= 1), (2 < 3) >= 1 union select * from v1;
+2 < 3 >= 1 2 < (3 >= 1) (2 < 3) >= 1
+1 0 1
+create or replace view v1 as select 2 < 3 <= 3, 2 < (3 <= 3), (2 < 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 <= 3 AS `2 < 3 <= 3`,2 < (3 <= 3) AS `2 < (3 <= 3)`,2 < 3 <= 3 AS `(2 < 3) <= 3`
+select 2 < 3 <= 3, 2 < (3 <= 3), (2 < 3) <= 3 union select * from v1;
+2 < 3 <= 3 2 < (3 <= 3) (2 < 3) <= 3
+1 0 1
+create or replace view v1 as select 2 < 3 < 3, 2 < (3 < 3), (2 < 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 < 3 AS `2 < 3 < 3`,2 < (3 < 3) AS `2 < (3 < 3)`,2 < 3 < 3 AS `(2 < 3) < 3`
+select 2 < 3 < 3, 2 < (3 < 3), (2 < 3) < 3 union select * from v1;
+2 < 3 < 3 2 < (3 < 3) (2 < 3) < 3
+1 0 1
+create or replace view v1 as select 2 < 3 <> 3, 2 < (3 <> 3), (2 < 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 <> 3 AS `2 < 3 <> 3`,2 < (3 <> 3) AS `2 < (3 <> 3)`,2 < 3 <> 3 AS `(2 < 3) <> 3`
+select 2 < 3 <> 3, 2 < (3 <> 3), (2 < 3) <> 3 union select * from v1;
+2 < 3 <> 3 2 < (3 <> 3) (2 < 3) <> 3
+1 0 1
+create or replace view v1 as select 2 < 3 > 0, 2 < (3 > 0), (2 < 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 > 0 AS `2 < 3 > 0`,2 < (3 > 0) AS `2 < (3 > 0)`,2 < 3 > 0 AS `(2 < 3) > 0`
+select 2 < 3 > 0, 2 < (3 > 0), (2 < 3) > 0 union select * from v1;
+2 < 3 > 0 2 < (3 > 0) (2 < 3) > 0
+1 0 1
+create or replace view v1 as select 2 < 3 != 3, 2 < (3 != 3), (2 < 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 <> 3 AS `2 < 3 != 3`,2 < (3 <> 3) AS `2 < (3 != 3)`,2 < 3 <> 3 AS `(2 < 3) != 3`
+select 2 < 3 != 3, 2 < (3 != 3), (2 < 3) != 3 union select * from v1;
+2 < 3 != 3 2 < (3 != 3) (2 < 3) != 3
+1 0 1
+create or replace view v1 as select 2 < 3 LIKE 1, 2 < (3 LIKE 1), (2 < 3) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 like 1 AS `2 < 3 LIKE 1`,2 < 3 like 1 AS `2 < (3 LIKE 1)`,(2 < 3) like 1 AS `(2 < 3) LIKE 1`
+select 2 < 3 LIKE 1, 2 < (3 LIKE 1), (2 < 3) LIKE 1 union select * from v1;
+2 < 3 LIKE 1 2 < (3 LIKE 1) (2 < 3) LIKE 1
+0 0 1
+create or replace view v1 as select 2 < 3 REGEXP 1, 2 < (3 REGEXP 1), (2 < 3) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 regexp 1 AS `2 < 3 REGEXP 1`,2 < 3 regexp 1 AS `2 < (3 REGEXP 1)`,(2 < 3) regexp 1 AS `(2 < 3) REGEXP 1`
+select 2 < 3 REGEXP 1, 2 < (3 REGEXP 1), (2 < 3) REGEXP 1 union select * from v1;
+2 < 3 REGEXP 1 2 < (3 REGEXP 1) (2 < 3) REGEXP 1
+0 0 1
+create or replace view v1 as select 2 < 3 | 3, 2 < (3 | 3), (2 < 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 | 3 AS `2 < 3 | 3`,2 < 3 | 3 AS `2 < (3 | 3)`,(2 < 3) | 3 AS `(2 < 3) | 3`
+select 2 < 3 | 3, 2 < (3 | 3), (2 < 3) | 3 union select * from v1;
+2 < 3 | 3 2 < (3 | 3) (2 < 3) | 3
+1 1 3
+create or replace view v1 as select 2 < 4 & 4, 2 < (4 & 4), (2 < 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 4 & 4 AS `2 < 4 & 4`,2 < 4 & 4 AS `2 < (4 & 4)`,(2 < 4) & 4 AS `(2 < 4) & 4`
+select 2 < 4 & 4, 2 < (4 & 4), (2 < 4) & 4 union select * from v1;
+2 < 4 & 4 2 < (4 & 4) (2 < 4) & 4
+1 1 0
+create or replace view v1 as select 2 < 3 << 3, 2 < (3 << 3), (2 < 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 << 3 AS `2 < 3 << 3`,2 < 3 << 3 AS `2 < (3 << 3)`,(2 < 3) << 3 AS `(2 < 3) << 3`
+select 2 < 3 << 3, 2 < (3 << 3), (2 < 3) << 3 union select * from v1;
+2 < 3 << 3 2 < (3 << 3) (2 < 3) << 3
+1 1 8
+create or replace view v1 as select 0 < 3 >> 1, 0 < (3 >> 1), (0 < 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 < 3 >> 1 AS `0 < 3 >> 1`,0 < 3 >> 1 AS `0 < (3 >> 1)`,(0 < 3) >> 1 AS `(0 < 3) >> 1`
+select 0 < 3 >> 1, 0 < (3 >> 1), (0 < 3) >> 1 union select * from v1;
+0 < 3 >> 1 0 < (3 >> 1) (0 < 3) >> 1
+1 1 0
+create or replace view v1 as select 2 < '2000-01-01' +INTERVAL 1 DAY, 2 < ('2000-01-01' +INTERVAL 1 DAY), (2 < '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < '2000-01-01' + interval 1 day AS `2 < '2000-01-01' +INTERVAL 1 DAY`,2 < '2000-01-01' + interval 1 day AS `2 < ('2000-01-01' +INTERVAL 1 DAY)`,(2 < '2000-01-01') + interval 1 day AS `(2 < '2000-01-01') +INTERVAL 1 DAY`
+select 2 < '2000-01-01' +INTERVAL 1 DAY, 2 < ('2000-01-01' +INTERVAL 1 DAY), (2 < '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 < '2000-01-01' +INTERVAL 1 DAY 2 < ('2000-01-01' +INTERVAL 1 DAY) (2 < '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 < 3 + 3, 2 < (3 + 3), (2 < 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 + 3 AS `2 < 3 + 3`,2 < 3 + 3 AS `2 < (3 + 3)`,(2 < 3) + 3 AS `(2 < 3) + 3`
+select 2 < 3 + 3, 2 < (3 + 3), (2 < 3) + 3 union select * from v1;
+2 < 3 + 3 2 < (3 + 3) (2 < 3) + 3
+1 1 4
+create or replace view v1 as select 2 < 3 - 3, 2 < (3 - 3), (2 < 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 - 3 AS `2 < 3 - 3`,2 < 3 - 3 AS `2 < (3 - 3)`,(2 < 3) - 3 AS `(2 < 3) - 3`
+select 2 < 3 - 3, 2 < (3 - 3), (2 < 3) - 3 union select * from v1;
+2 < 3 - 3 2 < (3 - 3) (2 < 3) - 3
+0 0 -2
+create or replace view v1 as select 2 < 3 * 3, 2 < (3 * 3), (2 < 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 * 3 AS `2 < 3 * 3`,2 < 3 * 3 AS `2 < (3 * 3)`,(2 < 3) * 3 AS `(2 < 3) * 3`
+select 2 < 3 * 3, 2 < (3 * 3), (2 < 3) * 3 union select * from v1;
+2 < 3 * 3 2 < (3 * 3) (2 < 3) * 3
+1 1 3
+create or replace view v1 as select 2 < 3 / 3, 2 < (3 / 3), (2 < 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 / 3 AS `2 < 3 / 3`,2 < 3 / 3 AS `2 < (3 / 3)`,(2 < 3) / 3 AS `(2 < 3) / 3`
+select 2 < 3 / 3, 2 < (3 / 3), (2 < 3) / 3 union select * from v1;
+2 < 3 / 3 2 < (3 / 3) (2 < 3) / 3
+0 0 0.3333
+create or replace view v1 as select 2 < 9 DIV 3, 2 < (9 DIV 3), (2 < 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 9 DIV 3 AS `2 < 9 DIV 3`,2 < 9 DIV 3 AS `2 < (9 DIV 3)`,(2 < 9) DIV 3 AS `(2 < 9) DIV 3`
+select 2 < 9 DIV 3, 2 < (9 DIV 3), (2 < 9) DIV 3 union select * from v1;
+2 < 9 DIV 3 2 < (9 DIV 3) (2 < 9) DIV 3
+1 1 0
+create or replace view v1 as select 2 < 3 MOD 3, 2 < (3 MOD 3), (2 < 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 MOD 3 AS `2 < 3 MOD 3`,2 < 3 MOD 3 AS `2 < (3 MOD 3)`,(2 < 3) MOD 3 AS `(2 < 3) MOD 3`
+select 2 < 3 MOD 3, 2 < (3 MOD 3), (2 < 3) MOD 3 union select * from v1;
+2 < 3 MOD 3 2 < (3 MOD 3) (2 < 3) MOD 3
+0 0 1
+create or replace view v1 as select 2 < 3 % 3, 2 < (3 % 3), (2 < 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 MOD 3 AS `2 < 3 % 3`,2 < 3 MOD 3 AS `2 < (3 % 3)`,(2 < 3) MOD 3 AS `(2 < 3) % 3`
+select 2 < 3 % 3, 2 < (3 % 3), (2 < 3) % 3 union select * from v1;
+2 < 3 % 3 2 < (3 % 3) (2 < 3) % 3
+0 0 1
+create or replace view v1 as select 2 < 3 ^ 3, 2 < (3 ^ 3), (2 < 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 ^ 3 AS `2 < 3 ^ 3`,2 < 3 ^ 3 AS `2 < (3 ^ 3)`,(2 < 3) ^ 3 AS `(2 < 3) ^ 3`
+select 2 < 3 ^ 3, 2 < (3 ^ 3), (2 < 3) ^ 3 union select * from v1;
+2 < 3 ^ 3 2 < (3 ^ 3) (2 < 3) ^ 3
+0 0 2
+create or replace view v1 as select 2 < 3 BETWEEN 1 AND 3, 2 < (3 BETWEEN 1 AND 3), (2 < 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 between 1 and 3 AS `2 < 3 BETWEEN 1 AND 3`,2 < 3 between 1 and 3 AS `2 < (3 BETWEEN 1 AND 3)`,(2 < 3) between 1 and 3 AS `(2 < 3) BETWEEN 1 AND 3`
+select 2 < 3 BETWEEN 1 AND 3, 2 < (3 BETWEEN 1 AND 3), (2 < 3) BETWEEN 1 AND 3 union select * from v1;
+2 < 3 BETWEEN 1 AND 3 2 < (3 BETWEEN 1 AND 3) (2 < 3) BETWEEN 1 AND 3
+0 0 1
+create or replace view v1 as select 2 <> 3 IS FALSE, 2 <> (3 IS FALSE), (2 <> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 is false AS `2 <> 3 IS FALSE`,2 <> (3 is false) AS `2 <> (3 IS FALSE)`,2 <> 3 is false AS `(2 <> 3) IS FALSE`
+select 2 <> 3 IS FALSE, 2 <> (3 IS FALSE), (2 <> 3) IS FALSE union select * from v1;
+2 <> 3 IS FALSE 2 <> (3 IS FALSE) (2 <> 3) IS FALSE
+0 1 0
+create or replace view v1 as select charset(2 <> 3 COLLATE latin1_bin), charset(2 <> (3 COLLATE latin1_bin)), charset((2 <> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 <> 3 collate latin1_bin) AS `charset(2 <> 3 COLLATE latin1_bin)`,charset(2 <> 3 collate latin1_bin) AS `charset(2 <> (3 COLLATE latin1_bin))`,charset((2 <> 3) collate latin1_bin) AS `charset((2 <> 3) COLLATE latin1_bin)`
+select charset(2 <> 3 COLLATE latin1_bin), charset(2 <> (3 COLLATE latin1_bin)), charset((2 <> 3) COLLATE latin1_bin) union select * from v1;
+charset(2 <> 3 COLLATE latin1_bin) charset(2 <> (3 COLLATE latin1_bin)) charset((2 <> 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 <> 3 IN (0,0), 2 <> (3 IN (0,0)), (2 <> 3) IN (0,0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 in (0,0) AS `2 <> 3 IN (0,0)`,2 <> 3 in (0,0) AS `2 <> (3 IN (0,0))`,(2 <> 3) in (0,0) AS `(2 <> 3) IN (0,0)`
+select 2 <> 3 IN (0,0), 2 <> (3 IN (0,0)), (2 <> 3) IN (0,0) union select * from v1;
+2 <> 3 IN (0,0) 2 <> (3 IN (0,0)) (2 <> 3) IN (0,0)
+1 1 0
+create or replace view v1 as select 1 <> 3 OR 3, 1 <> (3 OR 3), (1 <> 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 or 3 AS `1 <> 3 OR 3`,1 <> (3 or 3) AS `1 <> (3 OR 3)`,1 <> 3 or 3 AS `(1 <> 3) OR 3`
+select 1 <> 3 OR 3, 1 <> (3 OR 3), (1 <> 3) OR 3 union select * from v1;
+1 <> 3 OR 3 1 <> (3 OR 3) (1 <> 3) OR 3
+1 0 1
+create or replace view v1 as select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 or 3 AS `1 <> 3 || 3`,1 <> (3 or 3) AS `1 <> (3 || 3)`,1 <> 3 or 3 AS `(1 <> 3) || 3`
+select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3 union select * from v1;
+1 <> 3 || 3 1 <> (3 || 3) (1 <> 3) || 3
+1 0 1
+create or replace view v1 as select 2 <> 3 XOR 3, 2 <> (3 XOR 3), (2 <> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 xor 3 AS `2 <> 3 XOR 3`,2 <> (3 xor 3) AS `2 <> (3 XOR 3)`,2 <> 3 xor 3 AS `(2 <> 3) XOR 3`
+select 2 <> 3 XOR 3, 2 <> (3 XOR 3), (2 <> 3) XOR 3 union select * from v1;
+2 <> 3 XOR 3 2 <> (3 XOR 3) (2 <> 3) XOR 3
+0 1 0
+create or replace view v1 as select 3 <> 3 AND 3, 3 <> (3 AND 3), (3 <> 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 and 3 AS `3 <> 3 AND 3`,3 <> (3 and 3) AS `3 <> (3 AND 3)`,3 <> 3 and 3 AS `(3 <> 3) AND 3`
+select 3 <> 3 AND 3, 3 <> (3 AND 3), (3 <> 3) AND 3 union select * from v1;
+3 <> 3 AND 3 3 <> (3 AND 3) (3 <> 3) AND 3
+0 1 0
+create or replace view v1 as select 3 <> 3 && 3, 3 <> (3 && 3), (3 <> 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 and 3 AS `3 <> 3 && 3`,3 <> (3 and 3) AS `3 <> (3 && 3)`,3 <> 3 and 3 AS `(3 <> 3) && 3`
+select 3 <> 3 && 3, 3 <> (3 && 3), (3 <> 3) && 3 union select * from v1;
+3 <> 3 && 3 3 <> (3 && 3) (3 <> 3) && 3
+0 1 0
+create or replace view v1 as select 2 <> 3 = 3, 2 <> (3 = 3), (2 <> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 = 3 AS `2 <> 3 = 3`,2 <> (3 = 3) AS `2 <> (3 = 3)`,2 <> 3 = 3 AS `(2 <> 3) = 3`
+select 2 <> 3 = 3, 2 <> (3 = 3), (2 <> 3) = 3 union select * from v1;
+2 <> 3 = 3 2 <> (3 = 3) (2 <> 3) = 3
+0 1 0
+create or replace view v1 as select 2 <> 3 <=> 3, 2 <> (3 <=> 3), (2 <> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 <=> 3 AS `2 <> 3 <=> 3`,2 <> (3 <=> 3) AS `2 <> (3 <=> 3)`,2 <> 3 <=> 3 AS `(2 <> 3) <=> 3`
+select 2 <> 3 <=> 3, 2 <> (3 <=> 3), (2 <> 3) <=> 3 union select * from v1;
+2 <> 3 <=> 3 2 <> (3 <=> 3) (2 <> 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 <> 3 >= 3, 2 <> (3 >= 3), (2 <> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 >= 3 AS `2 <> 3 >= 3`,2 <> (3 >= 3) AS `2 <> (3 >= 3)`,2 <> 3 >= 3 AS `(2 <> 3) >= 3`
+select 2 <> 3 >= 3, 2 <> (3 >= 3), (2 <> 3) >= 3 union select * from v1;
+2 <> 3 >= 3 2 <> (3 >= 3) (2 <> 3) >= 3
+0 1 0
+create or replace view v1 as select 1 <> 3 <= 3, 1 <> (3 <= 3), (1 <> 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 <= 3 AS `1 <> 3 <= 3`,1 <> (3 <= 3) AS `1 <> (3 <= 3)`,1 <> 3 <= 3 AS `(1 <> 3) <= 3`
+select 1 <> 3 <= 3, 1 <> (3 <= 3), (1 <> 3) <= 3 union select * from v1;
+1 <> 3 <= 3 1 <> (3 <= 3) (1 <> 3) <= 3
+1 0 1
+create or replace view v1 as select 0 <> 3 < 3, 0 <> (3 < 3), (0 <> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 < 3 AS `0 <> 3 < 3`,0 <> (3 < 3) AS `0 <> (3 < 3)`,0 <> 3 < 3 AS `(0 <> 3) < 3`
+select 0 <> 3 < 3, 0 <> (3 < 3), (0 <> 3) < 3 union select * from v1;
+0 <> 3 < 3 0 <> (3 < 3) (0 <> 3) < 3
+1 0 1
+create or replace view v1 as select 0 <> 3 <> 3, 0 <> (3 <> 3), (0 <> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 <> 3 AS `0 <> 3 <> 3`,0 <> (3 <> 3) AS `0 <> (3 <> 3)`,0 <> 3 <> 3 AS `(0 <> 3) <> 3`
+select 0 <> 3 <> 3, 0 <> (3 <> 3), (0 <> 3) <> 3 union select * from v1;
+0 <> 3 <> 3 0 <> (3 <> 3) (0 <> 3) <> 3
+1 0 1
+create or replace view v1 as select 2 <> 3 > 3, 2 <> (3 > 3), (2 <> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 > 3 AS `2 <> 3 > 3`,2 <> (3 > 3) AS `2 <> (3 > 3)`,2 <> 3 > 3 AS `(2 <> 3) > 3`
+select 2 <> 3 > 3, 2 <> (3 > 3), (2 <> 3) > 3 union select * from v1;
+2 <> 3 > 3 2 <> (3 > 3) (2 <> 3) > 3
+0 1 0
+create or replace view v1 as select 0 <> 3 != 3, 0 <> (3 != 3), (0 <> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 <> 3 AS `0 <> 3 != 3`,0 <> (3 <> 3) AS `0 <> (3 != 3)`,0 <> 3 <> 3 AS `(0 <> 3) != 3`
+select 0 <> 3 != 3, 0 <> (3 != 3), (0 <> 3) != 3 union select * from v1;
+0 <> 3 != 3 0 <> (3 != 3) (0 <> 3) != 3
+1 0 1
+create or replace view v1 as select 2 <> 3 LIKE 3, 2 <> (3 LIKE 3), (2 <> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 like 3 AS `2 <> 3 LIKE 3`,2 <> 3 like 3 AS `2 <> (3 LIKE 3)`,(2 <> 3) like 3 AS `(2 <> 3) LIKE 3`
+select 2 <> 3 LIKE 3, 2 <> (3 LIKE 3), (2 <> 3) LIKE 3 union select * from v1;
+2 <> 3 LIKE 3 2 <> (3 LIKE 3) (2 <> 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 <> 3 REGEXP 3, 2 <> (3 REGEXP 3), (2 <> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 regexp 3 AS `2 <> 3 REGEXP 3`,2 <> 3 regexp 3 AS `2 <> (3 REGEXP 3)`,(2 <> 3) regexp 3 AS `(2 <> 3) REGEXP 3`
+select 2 <> 3 REGEXP 3, 2 <> (3 REGEXP 3), (2 <> 3) REGEXP 3 union select * from v1;
+2 <> 3 REGEXP 3 2 <> (3 REGEXP 3) (2 <> 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 <> 3 | 3, 2 <> (3 | 3), (2 <> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 | 3 AS `2 <> 3 | 3`,2 <> 3 | 3 AS `2 <> (3 | 3)`,(2 <> 3) | 3 AS `(2 <> 3) | 3`
+select 2 <> 3 | 3, 2 <> (3 | 3), (2 <> 3) | 3 union select * from v1;
+2 <> 3 | 3 2 <> (3 | 3) (2 <> 3) | 3
+1 1 3
+create or replace view v1 as select 2 <> 4 & 4, 2 <> (4 & 4), (2 <> 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 4 & 4 AS `2 <> 4 & 4`,2 <> 4 & 4 AS `2 <> (4 & 4)`,(2 <> 4) & 4 AS `(2 <> 4) & 4`
+select 2 <> 4 & 4, 2 <> (4 & 4), (2 <> 4) & 4 union select * from v1;
+2 <> 4 & 4 2 <> (4 & 4) (2 <> 4) & 4
+1 1 0
+create or replace view v1 as select 2 <> 3 << 3, 2 <> (3 << 3), (2 <> 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 << 3 AS `2 <> 3 << 3`,2 <> 3 << 3 AS `2 <> (3 << 3)`,(2 <> 3) << 3 AS `(2 <> 3) << 3`
+select 2 <> 3 << 3, 2 <> (3 << 3), (2 <> 3) << 3 union select * from v1;
+2 <> 3 << 3 2 <> (3 << 3) (2 <> 3) << 3
+1 1 8
+create or replace view v1 as select 2 <> 3 >> 3, 2 <> (3 >> 3), (2 <> 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 >> 3 AS `2 <> 3 >> 3`,2 <> 3 >> 3 AS `2 <> (3 >> 3)`,(2 <> 3) >> 3 AS `(2 <> 3) >> 3`
+select 2 <> 3 >> 3, 2 <> (3 >> 3), (2 <> 3) >> 3 union select * from v1;
+2 <> 3 >> 3 2 <> (3 >> 3) (2 <> 3) >> 3
+1 1 0
+create or replace view v1 as select 2 <> '2000-01-01' +INTERVAL 1 DAY, 2 <> ('2000-01-01' +INTERVAL 1 DAY), (2 <> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> '2000-01-01' + interval 1 day AS `2 <> '2000-01-01' +INTERVAL 1 DAY`,2 <> '2000-01-01' + interval 1 day AS `2 <> ('2000-01-01' +INTERVAL 1 DAY)`,(2 <> '2000-01-01') + interval 1 day AS `(2 <> '2000-01-01') +INTERVAL 1 DAY`
+select 2 <> '2000-01-01' +INTERVAL 1 DAY, 2 <> ('2000-01-01' +INTERVAL 1 DAY), (2 <> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 <> '2000-01-01' +INTERVAL 1 DAY 2 <> ('2000-01-01' +INTERVAL 1 DAY) (2 <> '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 <> 3 + 3, 2 <> (3 + 3), (2 <> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 + 3 AS `2 <> 3 + 3`,2 <> 3 + 3 AS `2 <> (3 + 3)`,(2 <> 3) + 3 AS `(2 <> 3) + 3`
+select 2 <> 3 + 3, 2 <> (3 + 3), (2 <> 3) + 3 union select * from v1;
+2 <> 3 + 3 2 <> (3 + 3) (2 <> 3) + 3
+1 1 4
+create or replace view v1 as select 2 <> 3 - 3, 2 <> (3 - 3), (2 <> 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 - 3 AS `2 <> 3 - 3`,2 <> 3 - 3 AS `2 <> (3 - 3)`,(2 <> 3) - 3 AS `(2 <> 3) - 3`
+select 2 <> 3 - 3, 2 <> (3 - 3), (2 <> 3) - 3 union select * from v1;
+2 <> 3 - 3 2 <> (3 - 3) (2 <> 3) - 3
+1 1 -2
+create or replace view v1 as select 2 <> 3 * 3, 2 <> (3 * 3), (2 <> 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 * 3 AS `2 <> 3 * 3`,2 <> 3 * 3 AS `2 <> (3 * 3)`,(2 <> 3) * 3 AS `(2 <> 3) * 3`
+select 2 <> 3 * 3, 2 <> (3 * 3), (2 <> 3) * 3 union select * from v1;
+2 <> 3 * 3 2 <> (3 * 3) (2 <> 3) * 3
+1 1 3
+create or replace view v1 as select 2 <> 3 / 3, 2 <> (3 / 3), (2 <> 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 / 3 AS `2 <> 3 / 3`,2 <> 3 / 3 AS `2 <> (3 / 3)`,(2 <> 3) / 3 AS `(2 <> 3) / 3`
+select 2 <> 3 / 3, 2 <> (3 / 3), (2 <> 3) / 3 union select * from v1;
+2 <> 3 / 3 2 <> (3 / 3) (2 <> 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 <> 3 DIV 3, 2 <> (3 DIV 3), (2 <> 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 DIV 3 AS `2 <> 3 DIV 3`,2 <> 3 DIV 3 AS `2 <> (3 DIV 3)`,(2 <> 3) DIV 3 AS `(2 <> 3) DIV 3`
+select 2 <> 3 DIV 3, 2 <> (3 DIV 3), (2 <> 3) DIV 3 union select * from v1;
+2 <> 3 DIV 3 2 <> (3 DIV 3) (2 <> 3) DIV 3
+1 1 0
+create or replace view v1 as select 3 <> 3 MOD 3, 3 <> (3 MOD 3), (3 <> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 MOD 3 AS `3 <> 3 MOD 3`,3 <> 3 MOD 3 AS `3 <> (3 MOD 3)`,(3 <> 3) MOD 3 AS `(3 <> 3) MOD 3`
+select 3 <> 3 MOD 3, 3 <> (3 MOD 3), (3 <> 3) MOD 3 union select * from v1;
+3 <> 3 MOD 3 3 <> (3 MOD 3) (3 <> 3) MOD 3
+1 1 0
+create or replace view v1 as select 3 <> 3 % 3, 3 <> (3 % 3), (3 <> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 MOD 3 AS `3 <> 3 % 3`,3 <> 3 MOD 3 AS `3 <> (3 % 3)`,(3 <> 3) MOD 3 AS `(3 <> 3) % 3`
+select 3 <> 3 % 3, 3 <> (3 % 3), (3 <> 3) % 3 union select * from v1;
+3 <> 3 % 3 3 <> (3 % 3) (3 <> 3) % 3
+1 1 0
+create or replace view v1 as select 2 <> 3 ^ 3, 2 <> (3 ^ 3), (2 <> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 ^ 3 AS `2 <> 3 ^ 3`,2 <> 3 ^ 3 AS `2 <> (3 ^ 3)`,(2 <> 3) ^ 3 AS `(2 <> 3) ^ 3`
+select 2 <> 3 ^ 3, 2 <> (3 ^ 3), (2 <> 3) ^ 3 union select * from v1;
+2 <> 3 ^ 3 2 <> (3 ^ 3) (2 <> 3) ^ 3
+1 1 2
+create or replace view v1 as select 2 <> 3 BETWEEN 2 AND 3, 2 <> (3 BETWEEN 2 AND 3), (2 <> 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 between 2 and 3 AS `2 <> 3 BETWEEN 2 AND 3`,2 <> 3 between 2 and 3 AS `2 <> (3 BETWEEN 2 AND 3)`,(2 <> 3) between 2 and 3 AS `(2 <> 3) BETWEEN 2 AND 3`
+select 2 <> 3 BETWEEN 2 AND 3, 2 <> (3 BETWEEN 2 AND 3), (2 <> 3) BETWEEN 2 AND 3 union select * from v1;
+2 <> 3 BETWEEN 2 AND 3 2 <> (3 BETWEEN 2 AND 3) (2 <> 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select 2 > 0 IS FALSE, 2 > (0 IS FALSE), (2 > 0) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 0 is false AS `2 > 0 IS FALSE`,2 > (0 is false) AS `2 > (0 IS FALSE)`,2 > 0 is false AS `(2 > 0) IS FALSE`
+select 2 > 0 IS FALSE, 2 > (0 IS FALSE), (2 > 0) IS FALSE union select * from v1;
+2 > 0 IS FALSE 2 > (0 IS FALSE) (2 > 0) IS FALSE
+0 1 0
+create or replace view v1 as select charset(2 > 3 COLLATE latin1_bin), charset(2 > (3 COLLATE latin1_bin)), charset((2 > 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 > 3 collate latin1_bin) AS `charset(2 > 3 COLLATE latin1_bin)`,charset(2 > 3 collate latin1_bin) AS `charset(2 > (3 COLLATE latin1_bin))`,charset((2 > 3) collate latin1_bin) AS `charset((2 > 3) COLLATE latin1_bin)`
+select charset(2 > 3 COLLATE latin1_bin), charset(2 > (3 COLLATE latin1_bin)), charset((2 > 3) COLLATE latin1_bin) union select * from v1;
+charset(2 > 3 COLLATE latin1_bin) charset(2 > (3 COLLATE latin1_bin)) charset((2 > 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 > 3 IN (1,1), 2 > (3 IN (1,1)), (2 > 3) IN (1,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 in (1,1) AS `2 > 3 IN (1,1)`,2 > 3 in (1,1) AS `2 > (3 IN (1,1))`,(2 > 3) in (1,1) AS `(2 > 3) IN (1,1)`
+select 2 > 3 IN (1,1), 2 > (3 IN (1,1)), (2 > 3) IN (1,1) union select * from v1;
+2 > 3 IN (1,1) 2 > (3 IN (1,1)) (2 > 3) IN (1,1)
+1 1 0
+create or replace view v1 as select 0 > 3 OR 3, 0 > (3 OR 3), (0 > 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 > 3 or 3 AS `0 > 3 OR 3`,0 > (3 or 3) AS `0 > (3 OR 3)`,0 > 3 or 3 AS `(0 > 3) OR 3`
+select 0 > 3 OR 3, 0 > (3 OR 3), (0 > 3) OR 3 union select * from v1;
+0 > 3 OR 3 0 > (3 OR 3) (0 > 3) OR 3
+1 0 1
+create or replace view v1 as select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 > 3 or 3 AS `0 > 3 || 3`,0 > (3 or 3) AS `0 > (3 || 3)`,0 > 3 or 3 AS `(0 > 3) || 3`
+select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3 union select * from v1;
+0 > 3 || 3 0 > (3 || 3) (0 > 3) || 3
+1 0 1
+create or replace view v1 as select 4 > 3 XOR 3, 4 > (3 XOR 3), (4 > 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 > 3 xor 3 AS `4 > 3 XOR 3`,4 > (3 xor 3) AS `4 > (3 XOR 3)`,4 > 3 xor 3 AS `(4 > 3) XOR 3`
+select 4 > 3 XOR 3, 4 > (3 XOR 3), (4 > 3) XOR 3 union select * from v1;
+4 > 3 XOR 3 4 > (3 XOR 3) (4 > 3) XOR 3
+0 1 0
+create or replace view v1 as select 2 > 3 AND 3, 2 > (3 AND 3), (2 > 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 and 3 AS `2 > 3 AND 3`,2 > (3 and 3) AS `2 > (3 AND 3)`,2 > 3 and 3 AS `(2 > 3) AND 3`
+select 2 > 3 AND 3, 2 > (3 AND 3), (2 > 3) AND 3 union select * from v1;
+2 > 3 AND 3 2 > (3 AND 3) (2 > 3) AND 3
+0 1 0
+create or replace view v1 as select 2 > 3 && 3, 2 > (3 && 3), (2 > 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 and 3 AS `2 > 3 && 3`,2 > (3 and 3) AS `2 > (3 && 3)`,2 > 3 and 3 AS `(2 > 3) && 3`
+select 2 > 3 && 3, 2 > (3 && 3), (2 > 3) && 3 union select * from v1;
+2 > 3 && 3 2 > (3 && 3) (2 > 3) && 3
+0 1 0
+create or replace view v1 as select 2 > 3 = 3, 2 > (3 = 3), (2 > 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 = 3 AS `2 > 3 = 3`,2 > (3 = 3) AS `2 > (3 = 3)`,2 > 3 = 3 AS `(2 > 3) = 3`
+select 2 > 3 = 3, 2 > (3 = 3), (2 > 3) = 3 union select * from v1;
+2 > 3 = 3 2 > (3 = 3) (2 > 3) = 3
+0 1 0
+create or replace view v1 as select 2 > 3 <=> 3, 2 > (3 <=> 3), (2 > 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 <=> 3 AS `2 > 3 <=> 3`,2 > (3 <=> 3) AS `2 > (3 <=> 3)`,2 > 3 <=> 3 AS `(2 > 3) <=> 3`
+select 2 > 3 <=> 3, 2 > (3 <=> 3), (2 > 3) <=> 3 union select * from v1;
+2 > 3 <=> 3 2 > (3 <=> 3) (2 > 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 > 3 >= 3, 2 > (3 >= 3), (2 > 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 >= 3 AS `2 > 3 >= 3`,2 > (3 >= 3) AS `2 > (3 >= 3)`,2 > 3 >= 3 AS `(2 > 3) >= 3`
+select 2 > 3 >= 3, 2 > (3 >= 3), (2 > 3) >= 3 union select * from v1;
+2 > 3 >= 3 2 > (3 >= 3) (2 > 3) >= 3
+0 1 0
+create or replace view v1 as select 2 > 0 <= 0, 2 > (0 <= 0), (2 > 0) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 0 <= 0 AS `2 > 0 <= 0`,2 > (0 <= 0) AS `2 > (0 <= 0)`,2 > 0 <= 0 AS `(2 > 0) <= 0`
+select 2 > 0 <= 0, 2 > (0 <= 0), (2 > 0) <= 0 union select * from v1;
+2 > 0 <= 0 2 > (0 <= 0) (2 > 0) <= 0
+0 1 0
+create or replace view v1 as select 2 > 0 < 0, 2 > (0 < 0), (2 > 0) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 0 < 0 AS `2 > 0 < 0`,2 > (0 < 0) AS `2 > (0 < 0)`,2 > 0 < 0 AS `(2 > 0) < 0`
+select 2 > 0 < 0, 2 > (0 < 0), (2 > 0) < 0 union select * from v1;
+2 > 0 < 0 2 > (0 < 0) (2 > 0) < 0
+0 1 0
+create or replace view v1 as select 2 > 1 <> 1, 2 > (1 <> 1), (2 > 1) <> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 1 <> 1 AS `2 > 1 <> 1`,2 > (1 <> 1) AS `2 > (1 <> 1)`,2 > 1 <> 1 AS `(2 > 1) <> 1`
+select 2 > 1 <> 1, 2 > (1 <> 1), (2 > 1) <> 1 union select * from v1;
+2 > 1 <> 1 2 > (1 <> 1) (2 > 1) <> 1
+0 1 0
+create or replace view v1 as select 2 > 3 > 3, 2 > (3 > 3), (2 > 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 > 3 AS `2 > 3 > 3`,2 > (3 > 3) AS `2 > (3 > 3)`,2 > 3 > 3 AS `(2 > 3) > 3`
+select 2 > 3 > 3, 2 > (3 > 3), (2 > 3) > 3 union select * from v1;
+2 > 3 > 3 2 > (3 > 3) (2 > 3) > 3
+0 1 0
+create or replace view v1 as select 2 > 1 != 1, 2 > (1 != 1), (2 > 1) != 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 1 <> 1 AS `2 > 1 != 1`,2 > (1 <> 1) AS `2 > (1 != 1)`,2 > 1 <> 1 AS `(2 > 1) != 1`
+select 2 > 1 != 1, 2 > (1 != 1), (2 > 1) != 1 union select * from v1;
+2 > 1 != 1 2 > (1 != 1) (2 > 1) != 1
+0 1 0
+create or replace view v1 as select 2 > 3 LIKE 3, 2 > (3 LIKE 3), (2 > 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 like 3 AS `2 > 3 LIKE 3`,2 > 3 like 3 AS `2 > (3 LIKE 3)`,(2 > 3) like 3 AS `(2 > 3) LIKE 3`
+select 2 > 3 LIKE 3, 2 > (3 LIKE 3), (2 > 3) LIKE 3 union select * from v1;
+2 > 3 LIKE 3 2 > (3 LIKE 3) (2 > 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 > 3 REGEXP 3, 2 > (3 REGEXP 3), (2 > 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 regexp 3 AS `2 > 3 REGEXP 3`,2 > 3 regexp 3 AS `2 > (3 REGEXP 3)`,(2 > 3) regexp 3 AS `(2 > 3) REGEXP 3`
+select 2 > 3 REGEXP 3, 2 > (3 REGEXP 3), (2 > 3) REGEXP 3 union select * from v1;
+2 > 3 REGEXP 3 2 > (3 REGEXP 3) (2 > 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 > 3 | 3, 2 > (3 | 3), (2 > 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 | 3 AS `2 > 3 | 3`,2 > 3 | 3 AS `2 > (3 | 3)`,(2 > 3) | 3 AS `(2 > 3) | 3`
+select 2 > 3 | 3, 2 > (3 | 3), (2 > 3) | 3 union select * from v1;
+2 > 3 | 3 2 > (3 | 3) (2 > 3) | 3
+0 0 3
+create or replace view v1 as select 4 > 2 & 2, 4 > (2 & 2), (4 > 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 > 2 & 2 AS `4 > 2 & 2`,4 > 2 & 2 AS `4 > (2 & 2)`,(4 > 2) & 2 AS `(4 > 2) & 2`
+select 4 > 2 & 2, 4 > (2 & 2), (4 > 2) & 2 union select * from v1;
+4 > 2 & 2 4 > (2 & 2) (4 > 2) & 2
+1 1 0
+create or replace view v1 as select 4 > 3 << 3, 4 > (3 << 3), (4 > 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 > 3 << 3 AS `4 > 3 << 3`,4 > 3 << 3 AS `4 > (3 << 3)`,(4 > 3) << 3 AS `(4 > 3) << 3`
+select 4 > 3 << 3, 4 > (3 << 3), (4 > 3) << 3 union select * from v1;
+4 > 3 << 3 4 > (3 << 3) (4 > 3) << 3
+0 0 8
+create or replace view v1 as select 2 > 3 >> 3, 2 > (3 >> 3), (2 > 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 >> 3 AS `2 > 3 >> 3`,2 > 3 >> 3 AS `2 > (3 >> 3)`,(2 > 3) >> 3 AS `(2 > 3) >> 3`
+select 2 > 3 >> 3, 2 > (3 >> 3), (2 > 3) >> 3 union select * from v1;
+2 > 3 >> 3 2 > (3 >> 3) (2 > 3) >> 3
+1 1 0
+create or replace view v1 as select 2 > '2000-01-01' +INTERVAL 1 DAY, 2 > ('2000-01-01' +INTERVAL 1 DAY), (2 > '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > '2000-01-01' + interval 1 day AS `2 > '2000-01-01' +INTERVAL 1 DAY`,2 > '2000-01-01' + interval 1 day AS `2 > ('2000-01-01' +INTERVAL 1 DAY)`,(2 > '2000-01-01') + interval 1 day AS `(2 > '2000-01-01') +INTERVAL 1 DAY`
+select 2 > '2000-01-01' +INTERVAL 1 DAY, 2 > ('2000-01-01' +INTERVAL 1 DAY), (2 > '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 > '2000-01-01' +INTERVAL 1 DAY 2 > ('2000-01-01' +INTERVAL 1 DAY) (2 > '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 > 3 + 3, 2 > (3 + 3), (2 > 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 + 3 AS `2 > 3 + 3`,2 > 3 + 3 AS `2 > (3 + 3)`,(2 > 3) + 3 AS `(2 > 3) + 3`
+select 2 > 3 + 3, 2 > (3 + 3), (2 > 3) + 3 union select * from v1;
+2 > 3 + 3 2 > (3 + 3) (2 > 3) + 3
+0 0 3
+create or replace view v1 as select 2 > 3 - 3, 2 > (3 - 3), (2 > 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 - 3 AS `2 > 3 - 3`,2 > 3 - 3 AS `2 > (3 - 3)`,(2 > 3) - 3 AS `(2 > 3) - 3`
+select 2 > 3 - 3, 2 > (3 - 3), (2 > 3) - 3 union select * from v1;
+2 > 3 - 3 2 > (3 - 3) (2 > 3) - 3
+1 1 -3
+create or replace view v1 as select 4 > 3 * 3, 4 > (3 * 3), (4 > 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 > 3 * 3 AS `4 > 3 * 3`,4 > 3 * 3 AS `4 > (3 * 3)`,(4 > 3) * 3 AS `(4 > 3) * 3`
+select 4 > 3 * 3, 4 > (3 * 3), (4 > 3) * 3 union select * from v1;
+4 > 3 * 3 4 > (3 * 3) (4 > 3) * 3
+0 0 3
+create or replace view v1 as select 2 > 3 / 3, 2 > (3 / 3), (2 > 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 / 3 AS `2 > 3 / 3`,2 > 3 / 3 AS `2 > (3 / 3)`,(2 > 3) / 3 AS `(2 > 3) / 3`
+select 2 > 3 / 3, 2 > (3 / 3), (2 > 3) / 3 union select * from v1;
+2 > 3 / 3 2 > (3 / 3) (2 > 3) / 3
+1 1 0.0000
+create or replace view v1 as select 2 > 3 DIV 3, 2 > (3 DIV 3), (2 > 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 DIV 3 AS `2 > 3 DIV 3`,2 > 3 DIV 3 AS `2 > (3 DIV 3)`,(2 > 3) DIV 3 AS `(2 > 3) DIV 3`
+select 2 > 3 DIV 3, 2 > (3 DIV 3), (2 > 3) DIV 3 union select * from v1;
+2 > 3 DIV 3 2 > (3 DIV 3) (2 > 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 > 3 MOD 3, 2 > (3 MOD 3), (2 > 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 MOD 3 AS `2 > 3 MOD 3`,2 > 3 MOD 3 AS `2 > (3 MOD 3)`,(2 > 3) MOD 3 AS `(2 > 3) MOD 3`
+select 2 > 3 MOD 3, 2 > (3 MOD 3), (2 > 3) MOD 3 union select * from v1;
+2 > 3 MOD 3 2 > (3 MOD 3) (2 > 3) MOD 3
+1 1 0
+create or replace view v1 as select 2 > 3 % 3, 2 > (3 % 3), (2 > 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 MOD 3 AS `2 > 3 % 3`,2 > 3 MOD 3 AS `2 > (3 % 3)`,(2 > 3) MOD 3 AS `(2 > 3) % 3`
+select 2 > 3 % 3, 2 > (3 % 3), (2 > 3) % 3 union select * from v1;
+2 > 3 % 3 2 > (3 % 3) (2 > 3) % 3
+1 1 0
+create or replace view v1 as select 2 > 3 ^ 3, 2 > (3 ^ 3), (2 > 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 ^ 3 AS `2 > 3 ^ 3`,2 > 3 ^ 3 AS `2 > (3 ^ 3)`,(2 > 3) ^ 3 AS `(2 > 3) ^ 3`
+select 2 > 3 ^ 3, 2 > (3 ^ 3), (2 > 3) ^ 3 union select * from v1;
+2 > 3 ^ 3 2 > (3 ^ 3) (2 > 3) ^ 3
+1 1 3
+create or replace view v1 as select 2 > 3 BETWEEN 1 AND 3, 2 > (3 BETWEEN 1 AND 3), (2 > 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 between 1 and 3 AS `2 > 3 BETWEEN 1 AND 3`,2 > 3 between 1 and 3 AS `2 > (3 BETWEEN 1 AND 3)`,(2 > 3) between 1 and 3 AS `(2 > 3) BETWEEN 1 AND 3`
+select 2 > 3 BETWEEN 1 AND 3, 2 > (3 BETWEEN 1 AND 3), (2 > 3) BETWEEN 1 AND 3 union select * from v1;
+2 > 3 BETWEEN 1 AND 3 2 > (3 BETWEEN 1 AND 3) (2 > 3) BETWEEN 1 AND 3
+1 1 0
+create or replace view v1 as select 2 != 3 IS FALSE, 2 != (3 IS FALSE), (2 != 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 is false AS `2 != 3 IS FALSE`,2 <> (3 is false) AS `2 != (3 IS FALSE)`,2 <> 3 is false AS `(2 != 3) IS FALSE`
+select 2 != 3 IS FALSE, 2 != (3 IS FALSE), (2 != 3) IS FALSE union select * from v1;
+2 != 3 IS FALSE 2 != (3 IS FALSE) (2 != 3) IS FALSE
+0 1 0
+create or replace view v1 as select charset(2 != 3 COLLATE latin1_bin), charset(2 != (3 COLLATE latin1_bin)), charset((2 != 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 <> 3 collate latin1_bin) AS `charset(2 != 3 COLLATE latin1_bin)`,charset(2 <> 3 collate latin1_bin) AS `charset(2 != (3 COLLATE latin1_bin))`,charset((2 <> 3) collate latin1_bin) AS `charset((2 != 3) COLLATE latin1_bin)`
+select charset(2 != 3 COLLATE latin1_bin), charset(2 != (3 COLLATE latin1_bin)), charset((2 != 3) COLLATE latin1_bin) union select * from v1;
+charset(2 != 3 COLLATE latin1_bin) charset(2 != (3 COLLATE latin1_bin)) charset((2 != 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 != 3 IN (0,0), 2 != (3 IN (0,0)), (2 != 3) IN (0,0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 in (0,0) AS `2 != 3 IN (0,0)`,2 <> 3 in (0,0) AS `2 != (3 IN (0,0))`,(2 <> 3) in (0,0) AS `(2 != 3) IN (0,0)`
+select 2 != 3 IN (0,0), 2 != (3 IN (0,0)), (2 != 3) IN (0,0) union select * from v1;
+2 != 3 IN (0,0) 2 != (3 IN (0,0)) (2 != 3) IN (0,0)
+1 1 0
+create or replace view v1 as select 1 != 3 OR 3, 1 != (3 OR 3), (1 != 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 or 3 AS `1 != 3 OR 3`,1 <> (3 or 3) AS `1 != (3 OR 3)`,1 <> 3 or 3 AS `(1 != 3) OR 3`
+select 1 != 3 OR 3, 1 != (3 OR 3), (1 != 3) OR 3 union select * from v1;
+1 != 3 OR 3 1 != (3 OR 3) (1 != 3) OR 3
+1 0 1
+create or replace view v1 as select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 or 3 AS `1 != 3 || 3`,1 <> (3 or 3) AS `1 != (3 || 3)`,1 <> 3 or 3 AS `(1 != 3) || 3`
+select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3 union select * from v1;
+1 != 3 || 3 1 != (3 || 3) (1 != 3) || 3
+1 0 1
+create or replace view v1 as select 2 != 3 XOR 3, 2 != (3 XOR 3), (2 != 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 xor 3 AS `2 != 3 XOR 3`,2 <> (3 xor 3) AS `2 != (3 XOR 3)`,2 <> 3 xor 3 AS `(2 != 3) XOR 3`
+select 2 != 3 XOR 3, 2 != (3 XOR 3), (2 != 3) XOR 3 union select * from v1;
+2 != 3 XOR 3 2 != (3 XOR 3) (2 != 3) XOR 3
+0 1 0
+create or replace view v1 as select 3 != 3 AND 3, 3 != (3 AND 3), (3 != 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 and 3 AS `3 != 3 AND 3`,3 <> (3 and 3) AS `3 != (3 AND 3)`,3 <> 3 and 3 AS `(3 != 3) AND 3`
+select 3 != 3 AND 3, 3 != (3 AND 3), (3 != 3) AND 3 union select * from v1;
+3 != 3 AND 3 3 != (3 AND 3) (3 != 3) AND 3
+0 1 0
+create or replace view v1 as select 3 != 3 && 3, 3 != (3 && 3), (3 != 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 and 3 AS `3 != 3 && 3`,3 <> (3 and 3) AS `3 != (3 && 3)`,3 <> 3 and 3 AS `(3 != 3) && 3`
+select 3 != 3 && 3, 3 != (3 && 3), (3 != 3) && 3 union select * from v1;
+3 != 3 && 3 3 != (3 && 3) (3 != 3) && 3
+0 1 0
+create or replace view v1 as select 2 != 3 = 3, 2 != (3 = 3), (2 != 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 = 3 AS `2 != 3 = 3`,2 <> (3 = 3) AS `2 != (3 = 3)`,2 <> 3 = 3 AS `(2 != 3) = 3`
+select 2 != 3 = 3, 2 != (3 = 3), (2 != 3) = 3 union select * from v1;
+2 != 3 = 3 2 != (3 = 3) (2 != 3) = 3
+0 1 0
+create or replace view v1 as select 2 != 3 <=> 3, 2 != (3 <=> 3), (2 != 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 <=> 3 AS `2 != 3 <=> 3`,2 <> (3 <=> 3) AS `2 != (3 <=> 3)`,2 <> 3 <=> 3 AS `(2 != 3) <=> 3`
+select 2 != 3 <=> 3, 2 != (3 <=> 3), (2 != 3) <=> 3 union select * from v1;
+2 != 3 <=> 3 2 != (3 <=> 3) (2 != 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 != 3 >= 3, 2 != (3 >= 3), (2 != 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 >= 3 AS `2 != 3 >= 3`,2 <> (3 >= 3) AS `2 != (3 >= 3)`,2 <> 3 >= 3 AS `(2 != 3) >= 3`
+select 2 != 3 >= 3, 2 != (3 >= 3), (2 != 3) >= 3 union select * from v1;
+2 != 3 >= 3 2 != (3 >= 3) (2 != 3) >= 3
+0 1 0
+create or replace view v1 as select 1 != 3 <= 3, 1 != (3 <= 3), (1 != 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 3 <= 3 AS `1 != 3 <= 3`,1 <> (3 <= 3) AS `1 != (3 <= 3)`,1 <> 3 <= 3 AS `(1 != 3) <= 3`
+select 1 != 3 <= 3, 1 != (3 <= 3), (1 != 3) <= 3 union select * from v1;
+1 != 3 <= 3 1 != (3 <= 3) (1 != 3) <= 3
+1 0 1
+create or replace view v1 as select 0 != 3 < 3, 0 != (3 < 3), (0 != 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 < 3 AS `0 != 3 < 3`,0 <> (3 < 3) AS `0 != (3 < 3)`,0 <> 3 < 3 AS `(0 != 3) < 3`
+select 0 != 3 < 3, 0 != (3 < 3), (0 != 3) < 3 union select * from v1;
+0 != 3 < 3 0 != (3 < 3) (0 != 3) < 3
+1 0 1
+create or replace view v1 as select 0 != 3 <> 3, 0 != (3 <> 3), (0 != 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 <> 3 AS `0 != 3 <> 3`,0 <> (3 <> 3) AS `0 != (3 <> 3)`,0 <> 3 <> 3 AS `(0 != 3) <> 3`
+select 0 != 3 <> 3, 0 != (3 <> 3), (0 != 3) <> 3 union select * from v1;
+0 != 3 <> 3 0 != (3 <> 3) (0 != 3) <> 3
+1 0 1
+create or replace view v1 as select 2 != 3 > 3, 2 != (3 > 3), (2 != 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 > 3 AS `2 != 3 > 3`,2 <> (3 > 3) AS `2 != (3 > 3)`,2 <> 3 > 3 AS `(2 != 3) > 3`
+select 2 != 3 > 3, 2 != (3 > 3), (2 != 3) > 3 union select * from v1;
+2 != 3 > 3 2 != (3 > 3) (2 != 3) > 3
+0 1 0
+create or replace view v1 as select 0 != 3 != 3, 0 != (3 != 3), (0 != 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 <> 3 <> 3 AS `0 != 3 != 3`,0 <> (3 <> 3) AS `0 != (3 != 3)`,0 <> 3 <> 3 AS `(0 != 3) != 3`
+select 0 != 3 != 3, 0 != (3 != 3), (0 != 3) != 3 union select * from v1;
+0 != 3 != 3 0 != (3 != 3) (0 != 3) != 3
+1 0 1
+create or replace view v1 as select 2 != 3 LIKE 3, 2 != (3 LIKE 3), (2 != 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 like 3 AS `2 != 3 LIKE 3`,2 <> 3 like 3 AS `2 != (3 LIKE 3)`,(2 <> 3) like 3 AS `(2 != 3) LIKE 3`
+select 2 != 3 LIKE 3, 2 != (3 LIKE 3), (2 != 3) LIKE 3 union select * from v1;
+2 != 3 LIKE 3 2 != (3 LIKE 3) (2 != 3) LIKE 3
+1 1 0
+create or replace view v1 as select 2 != 3 REGEXP 3, 2 != (3 REGEXP 3), (2 != 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 regexp 3 AS `2 != 3 REGEXP 3`,2 <> 3 regexp 3 AS `2 != (3 REGEXP 3)`,(2 <> 3) regexp 3 AS `(2 != 3) REGEXP 3`
+select 2 != 3 REGEXP 3, 2 != (3 REGEXP 3), (2 != 3) REGEXP 3 union select * from v1;
+2 != 3 REGEXP 3 2 != (3 REGEXP 3) (2 != 3) REGEXP 3
+1 1 0
+create or replace view v1 as select 2 != 3 | 3, 2 != (3 | 3), (2 != 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 | 3 AS `2 != 3 | 3`,2 <> 3 | 3 AS `2 != (3 | 3)`,(2 <> 3) | 3 AS `(2 != 3) | 3`
+select 2 != 3 | 3, 2 != (3 | 3), (2 != 3) | 3 union select * from v1;
+2 != 3 | 3 2 != (3 | 3) (2 != 3) | 3
+1 1 3
+create or replace view v1 as select 2 != 4 & 4, 2 != (4 & 4), (2 != 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 4 & 4 AS `2 != 4 & 4`,2 <> 4 & 4 AS `2 != (4 & 4)`,(2 <> 4) & 4 AS `(2 != 4) & 4`
+select 2 != 4 & 4, 2 != (4 & 4), (2 != 4) & 4 union select * from v1;
+2 != 4 & 4 2 != (4 & 4) (2 != 4) & 4
+1 1 0
+create or replace view v1 as select 2 != 3 << 3, 2 != (3 << 3), (2 != 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 << 3 AS `2 != 3 << 3`,2 <> 3 << 3 AS `2 != (3 << 3)`,(2 <> 3) << 3 AS `(2 != 3) << 3`
+select 2 != 3 << 3, 2 != (3 << 3), (2 != 3) << 3 union select * from v1;
+2 != 3 << 3 2 != (3 << 3) (2 != 3) << 3
+1 1 8
+create or replace view v1 as select 2 != 3 >> 3, 2 != (3 >> 3), (2 != 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 >> 3 AS `2 != 3 >> 3`,2 <> 3 >> 3 AS `2 != (3 >> 3)`,(2 <> 3) >> 3 AS `(2 != 3) >> 3`
+select 2 != 3 >> 3, 2 != (3 >> 3), (2 != 3) >> 3 union select * from v1;
+2 != 3 >> 3 2 != (3 >> 3) (2 != 3) >> 3
+1 1 0
+create or replace view v1 as select 2 != '2000-01-01' +INTERVAL 1 DAY, 2 != ('2000-01-01' +INTERVAL 1 DAY), (2 != '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> '2000-01-01' + interval 1 day AS `2 != '2000-01-01' +INTERVAL 1 DAY`,2 <> '2000-01-01' + interval 1 day AS `2 != ('2000-01-01' +INTERVAL 1 DAY)`,(2 <> '2000-01-01') + interval 1 day AS `(2 != '2000-01-01') +INTERVAL 1 DAY`
+select 2 != '2000-01-01' +INTERVAL 1 DAY, 2 != ('2000-01-01' +INTERVAL 1 DAY), (2 != '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 != '2000-01-01' +INTERVAL 1 DAY 2 != ('2000-01-01' +INTERVAL 1 DAY) (2 != '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 != 3 + 3, 2 != (3 + 3), (2 != 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 + 3 AS `2 != 3 + 3`,2 <> 3 + 3 AS `2 != (3 + 3)`,(2 <> 3) + 3 AS `(2 != 3) + 3`
+select 2 != 3 + 3, 2 != (3 + 3), (2 != 3) + 3 union select * from v1;
+2 != 3 + 3 2 != (3 + 3) (2 != 3) + 3
+1 1 4
+create or replace view v1 as select 2 != 3 - 3, 2 != (3 - 3), (2 != 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 - 3 AS `2 != 3 - 3`,2 <> 3 - 3 AS `2 != (3 - 3)`,(2 <> 3) - 3 AS `(2 != 3) - 3`
+select 2 != 3 - 3, 2 != (3 - 3), (2 != 3) - 3 union select * from v1;
+2 != 3 - 3 2 != (3 - 3) (2 != 3) - 3
+1 1 -2
+create or replace view v1 as select 2 != 3 * 3, 2 != (3 * 3), (2 != 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 * 3 AS `2 != 3 * 3`,2 <> 3 * 3 AS `2 != (3 * 3)`,(2 <> 3) * 3 AS `(2 != 3) * 3`
+select 2 != 3 * 3, 2 != (3 * 3), (2 != 3) * 3 union select * from v1;
+2 != 3 * 3 2 != (3 * 3) (2 != 3) * 3
+1 1 3
+create or replace view v1 as select 2 != 3 / 3, 2 != (3 / 3), (2 != 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 / 3 AS `2 != 3 / 3`,2 <> 3 / 3 AS `2 != (3 / 3)`,(2 <> 3) / 3 AS `(2 != 3) / 3`
+select 2 != 3 / 3, 2 != (3 / 3), (2 != 3) / 3 union select * from v1;
+2 != 3 / 3 2 != (3 / 3) (2 != 3) / 3
+1 1 0.3333
+create or replace view v1 as select 2 != 3 DIV 3, 2 != (3 DIV 3), (2 != 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 DIV 3 AS `2 != 3 DIV 3`,2 <> 3 DIV 3 AS `2 != (3 DIV 3)`,(2 <> 3) DIV 3 AS `(2 != 3) DIV 3`
+select 2 != 3 DIV 3, 2 != (3 DIV 3), (2 != 3) DIV 3 union select * from v1;
+2 != 3 DIV 3 2 != (3 DIV 3) (2 != 3) DIV 3
+1 1 0
+create or replace view v1 as select 3 != 3 MOD 3, 3 != (3 MOD 3), (3 != 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 MOD 3 AS `3 != 3 MOD 3`,3 <> 3 MOD 3 AS `3 != (3 MOD 3)`,(3 <> 3) MOD 3 AS `(3 != 3) MOD 3`
+select 3 != 3 MOD 3, 3 != (3 MOD 3), (3 != 3) MOD 3 union select * from v1;
+3 != 3 MOD 3 3 != (3 MOD 3) (3 != 3) MOD 3
+1 1 0
+create or replace view v1 as select 3 != 3 % 3, 3 != (3 % 3), (3 != 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 <> 3 MOD 3 AS `3 != 3 % 3`,3 <> 3 MOD 3 AS `3 != (3 % 3)`,(3 <> 3) MOD 3 AS `(3 != 3) % 3`
+select 3 != 3 % 3, 3 != (3 % 3), (3 != 3) % 3 union select * from v1;
+3 != 3 % 3 3 != (3 % 3) (3 != 3) % 3
+1 1 0
+create or replace view v1 as select 2 != 3 ^ 3, 2 != (3 ^ 3), (2 != 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 ^ 3 AS `2 != 3 ^ 3`,2 <> 3 ^ 3 AS `2 != (3 ^ 3)`,(2 <> 3) ^ 3 AS `(2 != 3) ^ 3`
+select 2 != 3 ^ 3, 2 != (3 ^ 3), (2 != 3) ^ 3 union select * from v1;
+2 != 3 ^ 3 2 != (3 ^ 3) (2 != 3) ^ 3
+1 1 2
+create or replace view v1 as select 2 != 3 BETWEEN 2 AND 3, 2 != (3 BETWEEN 2 AND 3), (2 != 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 between 2 and 3 AS `2 != 3 BETWEEN 2 AND 3`,2 <> 3 between 2 and 3 AS `2 != (3 BETWEEN 2 AND 3)`,(2 <> 3) between 2 and 3 AS `(2 != 3) BETWEEN 2 AND 3`
+select 2 != 3 BETWEEN 2 AND 3, 2 != (3 BETWEEN 2 AND 3), (2 != 3) BETWEEN 2 AND 3 union select * from v1;
+2 != 3 BETWEEN 2 AND 3 2 != (3 BETWEEN 2 AND 3) (2 != 3) BETWEEN 2 AND 3
+1 1 0
+create or replace view v1 as select 2 LIKE 3 IS FALSE, 2 LIKE (3 IS FALSE), (2 LIKE 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 is false AS `2 LIKE 3 IS FALSE`,2 like (3 is false) AS `2 LIKE (3 IS FALSE)`,2 like 3 is false AS `(2 LIKE 3) IS FALSE`
+select 2 LIKE 3 IS FALSE, 2 LIKE (3 IS FALSE), (2 LIKE 3) IS FALSE union select * from v1;
+2 LIKE 3 IS FALSE 2 LIKE (3 IS FALSE) (2 LIKE 3) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 LIKE 3 COLLATE latin1_bin), charset(2 LIKE (3 COLLATE latin1_bin)), charset((2 LIKE 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 like 3 collate latin1_bin) AS `charset(2 LIKE 3 COLLATE latin1_bin)`,charset(2 like 3 collate latin1_bin) AS `charset(2 LIKE (3 COLLATE latin1_bin))`,charset((2 like 3) collate latin1_bin) AS `charset((2 LIKE 3) COLLATE latin1_bin)`
+select charset(2 LIKE 3 COLLATE latin1_bin), charset(2 LIKE (3 COLLATE latin1_bin)), charset((2 LIKE 3) COLLATE latin1_bin) union select * from v1;
+charset(2 LIKE 3 COLLATE latin1_bin) charset(2 LIKE (3 COLLATE latin1_bin)) charset((2 LIKE 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 LIKE 3 IN (0,1), 2 LIKE (3 IN (0,1)), (2 LIKE 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 in (0,1) AS `2 LIKE 3 IN (0,1)`,2 like (3 in (0,1)) AS `2 LIKE (3 IN (0,1))`,2 like 3 in (0,1) AS `(2 LIKE 3) IN (0,1)`
+select 2 LIKE 3 IN (0,1), 2 LIKE (3 IN (0,1)), (2 LIKE 3) IN (0,1) union select * from v1;
+2 LIKE 3 IN (0,1) 2 LIKE (3 IN (0,1)) (2 LIKE 3) IN (0,1)
+1 0 1
+create or replace view v1 as select 2 LIKE 3 OR 3, 2 LIKE (3 OR 3), (2 LIKE 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 or 3 AS `2 LIKE 3 OR 3`,2 like (3 or 3) AS `2 LIKE (3 OR 3)`,2 like 3 or 3 AS `(2 LIKE 3) OR 3`
+select 2 LIKE 3 OR 3, 2 LIKE (3 OR 3), (2 LIKE 3) OR 3 union select * from v1;
+2 LIKE 3 OR 3 2 LIKE (3 OR 3) (2 LIKE 3) OR 3
+1 0 1
+create or replace view v1 as select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 or 3 AS `2 LIKE 3 || 3`,2 like (3 or 3) AS `2 LIKE (3 || 3)`,2 like 3 or 3 AS `(2 LIKE 3) || 3`
+select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3 union select * from v1;
+2 LIKE 3 || 3 2 LIKE (3 || 3) (2 LIKE 3) || 3
+1 0 1
+create or replace view v1 as select 2 LIKE 3 XOR 3, 2 LIKE (3 XOR 3), (2 LIKE 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 xor 3 AS `2 LIKE 3 XOR 3`,2 like (3 xor 3) AS `2 LIKE (3 XOR 3)`,2 like 3 xor 3 AS `(2 LIKE 3) XOR 3`
+select 2 LIKE 3 XOR 3, 2 LIKE (3 XOR 3), (2 LIKE 3) XOR 3 union select * from v1;
+2 LIKE 3 XOR 3 2 LIKE (3 XOR 3) (2 LIKE 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 LIKE 2 AND 2, 2 LIKE (2 AND 2), (2 LIKE 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 and 2 AS `2 LIKE 2 AND 2`,2 like (2 and 2) AS `2 LIKE (2 AND 2)`,2 like 2 and 2 AS `(2 LIKE 2) AND 2`
+select 2 LIKE 2 AND 2, 2 LIKE (2 AND 2), (2 LIKE 2) AND 2 union select * from v1;
+2 LIKE 2 AND 2 2 LIKE (2 AND 2) (2 LIKE 2) AND 2
+1 0 1
+create or replace view v1 as select 2 LIKE 2 && 2, 2 LIKE (2 && 2), (2 LIKE 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 and 2 AS `2 LIKE 2 && 2`,2 like (2 and 2) AS `2 LIKE (2 && 2)`,2 like 2 and 2 AS `(2 LIKE 2) && 2`
+select 2 LIKE 2 && 2, 2 LIKE (2 && 2), (2 LIKE 2) && 2 union select * from v1;
+2 LIKE 2 && 2 2 LIKE (2 && 2) (2 LIKE 2) && 2
+1 0 1
+create or replace view v1 as select 2 LIKE 2 = 1, 2 LIKE (2 = 1), (2 LIKE 2) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 = 1 AS `2 LIKE 2 = 1`,2 like (2 = 1) AS `2 LIKE (2 = 1)`,2 like 2 = 1 AS `(2 LIKE 2) = 1`
+select 2 LIKE 2 = 1, 2 LIKE (2 = 1), (2 LIKE 2) = 1 union select * from v1;
+2 LIKE 2 = 1 2 LIKE (2 = 1) (2 LIKE 2) = 1
+1 0 1
+create or replace view v1 as select 2 LIKE 2 <=> 1, 2 LIKE (2 <=> 1), (2 LIKE 2) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 <=> 1 AS `2 LIKE 2 <=> 1`,2 like (2 <=> 1) AS `2 LIKE (2 <=> 1)`,2 like 2 <=> 1 AS `(2 LIKE 2) <=> 1`
+select 2 LIKE 2 <=> 1, 2 LIKE (2 <=> 1), (2 LIKE 2) <=> 1 union select * from v1;
+2 LIKE 2 <=> 1 2 LIKE (2 <=> 1) (2 LIKE 2) <=> 1
+1 0 1
+create or replace view v1 as select 2 LIKE 2 >= 1, 2 LIKE (2 >= 1), (2 LIKE 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 >= 1 AS `2 LIKE 2 >= 1`,2 like (2 >= 1) AS `2 LIKE (2 >= 1)`,2 like 2 >= 1 AS `(2 LIKE 2) >= 1`
+select 2 LIKE 2 >= 1, 2 LIKE (2 >= 1), (2 LIKE 2) >= 1 union select * from v1;
+2 LIKE 2 >= 1 2 LIKE (2 >= 1) (2 LIKE 2) >= 1
+1 0 1
+create or replace view v1 as select 2 LIKE 3 <= 3, 2 LIKE (3 <= 3), (2 LIKE 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 <= 3 AS `2 LIKE 3 <= 3`,2 like (3 <= 3) AS `2 LIKE (3 <= 3)`,2 like 3 <= 3 AS `(2 LIKE 3) <= 3`
+select 2 LIKE 3 <= 3, 2 LIKE (3 <= 3), (2 LIKE 3) <= 3 union select * from v1;
+2 LIKE 3 <= 3 2 LIKE (3 <= 3) (2 LIKE 3) <= 3
+1 0 1
+create or replace view v1 as select 2 LIKE 3 < 3, 2 LIKE (3 < 3), (2 LIKE 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 < 3 AS `2 LIKE 3 < 3`,2 like (3 < 3) AS `2 LIKE (3 < 3)`,2 like 3 < 3 AS `(2 LIKE 3) < 3`
+select 2 LIKE 3 < 3, 2 LIKE (3 < 3), (2 LIKE 3) < 3 union select * from v1;
+2 LIKE 3 < 3 2 LIKE (3 < 3) (2 LIKE 3) < 3
+1 0 1
+create or replace view v1 as select 2 LIKE 3 <> 3, 2 LIKE (3 <> 3), (2 LIKE 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 <> 3 AS `2 LIKE 3 <> 3`,2 like (3 <> 3) AS `2 LIKE (3 <> 3)`,2 like 3 <> 3 AS `(2 LIKE 3) <> 3`
+select 2 LIKE 3 <> 3, 2 LIKE (3 <> 3), (2 LIKE 3) <> 3 union select * from v1;
+2 LIKE 3 <> 3 2 LIKE (3 <> 3) (2 LIKE 3) <> 3
+1 0 1
+create or replace view v1 as select 2 LIKE 2 > 0, 2 LIKE (2 > 0), (2 LIKE 2) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 > 0 AS `2 LIKE 2 > 0`,2 like (2 > 0) AS `2 LIKE (2 > 0)`,2 like 2 > 0 AS `(2 LIKE 2) > 0`
+select 2 LIKE 2 > 0, 2 LIKE (2 > 0), (2 LIKE 2) > 0 union select * from v1;
+2 LIKE 2 > 0 2 LIKE (2 > 0) (2 LIKE 2) > 0
+1 0 1
+create or replace view v1 as select 2 LIKE 3 != 3, 2 LIKE (3 != 3), (2 LIKE 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 <> 3 AS `2 LIKE 3 != 3`,2 like (3 <> 3) AS `2 LIKE (3 != 3)`,2 like 3 <> 3 AS `(2 LIKE 3) != 3`
+select 2 LIKE 3 != 3, 2 LIKE (3 != 3), (2 LIKE 3) != 3 union select * from v1;
+2 LIKE 3 != 3 2 LIKE (3 != 3) (2 LIKE 3) != 3
+1 0 1
+create or replace view v1 as select 2 LIKE 2 LIKE 1, 2 LIKE (2 LIKE 1), (2 LIKE 2) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 like 1 AS `2 LIKE 2 LIKE 1`,2 like (2 like 1) AS `2 LIKE (2 LIKE 1)`,2 like 2 like 1 AS `(2 LIKE 2) LIKE 1`
+select 2 LIKE 2 LIKE 1, 2 LIKE (2 LIKE 1), (2 LIKE 2) LIKE 1 union select * from v1;
+2 LIKE 2 LIKE 1 2 LIKE (2 LIKE 1) (2 LIKE 2) LIKE 1
+1 0 1
+create or replace view v1 as select 2 LIKE 2 REGEXP 1, 2 LIKE (2 REGEXP 1), (2 LIKE 2) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 regexp 1 AS `2 LIKE 2 REGEXP 1`,2 like (2 regexp 1) AS `2 LIKE (2 REGEXP 1)`,2 like 2 regexp 1 AS `(2 LIKE 2) REGEXP 1`
+select 2 LIKE 2 REGEXP 1, 2 LIKE (2 REGEXP 1), (2 LIKE 2) REGEXP 1 union select * from v1;
+2 LIKE 2 REGEXP 1 2 LIKE (2 REGEXP 1) (2 LIKE 2) REGEXP 1
+1 0 1
+create or replace view v1 as select 2 LIKE 3 | 3, 2 LIKE (3 | 3), (2 LIKE 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 | 3 AS `2 LIKE 3 | 3`,2 like 3 | 3 AS `2 LIKE (3 | 3)`,(2 like 3) | 3 AS `(2 LIKE 3) | 3`
+select 2 LIKE 3 | 3, 2 LIKE (3 | 3), (2 LIKE 3) | 3 union select * from v1;
+2 LIKE 3 | 3 2 LIKE (3 | 3) (2 LIKE 3) | 3
+0 0 3
+create or replace view v1 as select 2 LIKE 2 & 2, 2 LIKE (2 & 2), (2 LIKE 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 & 2 AS `2 LIKE 2 & 2`,2 like 2 & 2 AS `2 LIKE (2 & 2)`,(2 like 2) & 2 AS `(2 LIKE 2) & 2`
+select 2 LIKE 2 & 2, 2 LIKE (2 & 2), (2 LIKE 2) & 2 union select * from v1;
+2 LIKE 2 & 2 2 LIKE (2 & 2) (2 LIKE 2) & 2
+1 1 0
+create or replace view v1 as select 2 LIKE 2 << 2, 2 LIKE (2 << 2), (2 LIKE 2) << 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 << 2 AS `2 LIKE 2 << 2`,2 like 2 << 2 AS `2 LIKE (2 << 2)`,(2 like 2) << 2 AS `(2 LIKE 2) << 2`
+select 2 LIKE 2 << 2, 2 LIKE (2 << 2), (2 LIKE 2) << 2 union select * from v1;
+2 LIKE 2 << 2 2 LIKE (2 << 2) (2 LIKE 2) << 2
+0 0 4
+create or replace view v1 as select 2 LIKE 4 >> 1, 2 LIKE (4 >> 1), (2 LIKE 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 4 >> 1 AS `2 LIKE 4 >> 1`,2 like 4 >> 1 AS `2 LIKE (4 >> 1)`,(2 like 4) >> 1 AS `(2 LIKE 4) >> 1`
+select 2 LIKE 4 >> 1, 2 LIKE (4 >> 1), (2 LIKE 4) >> 1 union select * from v1;
+2 LIKE 4 >> 1 2 LIKE (4 >> 1) (2 LIKE 4) >> 1
+1 1 0
+create or replace view v1 as select 2 LIKE '2000-01-01' +INTERVAL 1 DAY, 2 LIKE ('2000-01-01' +INTERVAL 1 DAY), (2 LIKE '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like '2000-01-01' + interval 1 day AS `2 LIKE '2000-01-01' +INTERVAL 1 DAY`,2 like '2000-01-01' + interval 1 day AS `2 LIKE ('2000-01-01' +INTERVAL 1 DAY)`,(2 like '2000-01-01') + interval 1 day AS `(2 LIKE '2000-01-01') +INTERVAL 1 DAY`
+select 2 LIKE '2000-01-01' +INTERVAL 1 DAY, 2 LIKE ('2000-01-01' +INTERVAL 1 DAY), (2 LIKE '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 LIKE '2000-01-01' +INTERVAL 1 DAY 2 LIKE ('2000-01-01' +INTERVAL 1 DAY) (2 LIKE '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 LIKE 3 + 3, 2 LIKE (3 + 3), (2 LIKE 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 + 3 AS `2 LIKE 3 + 3`,2 like 3 + 3 AS `2 LIKE (3 + 3)`,(2 like 3) + 3 AS `(2 LIKE 3) + 3`
+select 2 LIKE 3 + 3, 2 LIKE (3 + 3), (2 LIKE 3) + 3 union select * from v1;
+2 LIKE 3 + 3 2 LIKE (3 + 3) (2 LIKE 3) + 3
+0 0 3
+create or replace view v1 as select 2 LIKE 3 - 3, 2 LIKE (3 - 3), (2 LIKE 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 - 3 AS `2 LIKE 3 - 3`,2 like 3 - 3 AS `2 LIKE (3 - 3)`,(2 like 3) - 3 AS `(2 LIKE 3) - 3`
+select 2 LIKE 3 - 3, 2 LIKE (3 - 3), (2 LIKE 3) - 3 union select * from v1;
+2 LIKE 3 - 3 2 LIKE (3 - 3) (2 LIKE 3) - 3
+0 0 -3
+create or replace view v1 as select 2 LIKE 2 * 2, 2 LIKE (2 * 2), (2 LIKE 2) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 * 2 AS `2 LIKE 2 * 2`,2 like 2 * 2 AS `2 LIKE (2 * 2)`,(2 like 2) * 2 AS `(2 LIKE 2) * 2`
+select 2 LIKE 2 * 2, 2 LIKE (2 * 2), (2 LIKE 2) * 2 union select * from v1;
+2 LIKE 2 * 2 2 LIKE (2 * 2) (2 LIKE 2) * 2
+0 0 2
+create or replace view v1 as select 2 LIKE 2 / 2, 2 LIKE (2 / 2), (2 LIKE 2) / 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 / 2 AS `2 LIKE 2 / 2`,2 like 2 / 2 AS `2 LIKE (2 / 2)`,(2 like 2) / 2 AS `(2 LIKE 2) / 2`
+select 2 LIKE 2 / 2, 2 LIKE (2 / 2), (2 LIKE 2) / 2 union select * from v1;
+2 LIKE 2 / 2 2 LIKE (2 / 2) (2 LIKE 2) / 2
+0 0 0.5000
+create or replace view v1 as select 2 LIKE 4 DIV 2, 2 LIKE (4 DIV 2), (2 LIKE 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 4 DIV 2 AS `2 LIKE 4 DIV 2`,2 like 4 DIV 2 AS `2 LIKE (4 DIV 2)`,(2 like 4) DIV 2 AS `(2 LIKE 4) DIV 2`
+select 2 LIKE 4 DIV 2, 2 LIKE (4 DIV 2), (2 LIKE 4) DIV 2 union select * from v1;
+2 LIKE 4 DIV 2 2 LIKE (4 DIV 2) (2 LIKE 4) DIV 2
+1 1 0
+create or replace view v1 as select 2 LIKE 2 MOD 2, 2 LIKE (2 MOD 2), (2 LIKE 2) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 MOD 2 AS `2 LIKE 2 MOD 2`,2 like 2 MOD 2 AS `2 LIKE (2 MOD 2)`,(2 like 2) MOD 2 AS `(2 LIKE 2) MOD 2`
+select 2 LIKE 2 MOD 2, 2 LIKE (2 MOD 2), (2 LIKE 2) MOD 2 union select * from v1;
+2 LIKE 2 MOD 2 2 LIKE (2 MOD 2) (2 LIKE 2) MOD 2
+0 0 1
+create or replace view v1 as select 2 LIKE 2 % 2, 2 LIKE (2 % 2), (2 LIKE 2) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 MOD 2 AS `2 LIKE 2 % 2`,2 like 2 MOD 2 AS `2 LIKE (2 % 2)`,(2 like 2) MOD 2 AS `(2 LIKE 2) % 2`
+select 2 LIKE 2 % 2, 2 LIKE (2 % 2), (2 LIKE 2) % 2 union select * from v1;
+2 LIKE 2 % 2 2 LIKE (2 % 2) (2 LIKE 2) % 2
+0 0 1
+create or replace view v1 as select 2 LIKE 3 ^ 3, 2 LIKE (3 ^ 3), (2 LIKE 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 ^ 3 AS `2 LIKE 3 ^ 3`,2 like 3 ^ 3 AS `2 LIKE (3 ^ 3)`,(2 like 3) ^ 3 AS `(2 LIKE 3) ^ 3`
+select 2 LIKE 3 ^ 3, 2 LIKE (3 ^ 3), (2 LIKE 3) ^ 3 union select * from v1;
+2 LIKE 3 ^ 3 2 LIKE (3 ^ 3) (2 LIKE 3) ^ 3
+0 0 3
+create or replace view v1 as select 2 LIKE 2 BETWEEN 1 AND 3, 2 LIKE (2 BETWEEN 1 AND 3), (2 LIKE 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 between 1 and 3 AS `2 LIKE 2 BETWEEN 1 AND 3`,2 like (2 between 1 and 3) AS `2 LIKE (2 BETWEEN 1 AND 3)`,2 like 2 between 1 and 3 AS `(2 LIKE 2) BETWEEN 1 AND 3`
+select 2 LIKE 2 BETWEEN 1 AND 3, 2 LIKE (2 BETWEEN 1 AND 3), (2 LIKE 2) BETWEEN 1 AND 3 union select * from v1;
+2 LIKE 2 BETWEEN 1 AND 3 2 LIKE (2 BETWEEN 1 AND 3) (2 LIKE 2) BETWEEN 1 AND 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 IS FALSE, 2 REGEXP (3 IS FALSE), (2 REGEXP 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 is false AS `2 REGEXP 3 IS FALSE`,2 regexp (3 is false) AS `2 REGEXP (3 IS FALSE)`,2 regexp 3 is false AS `(2 REGEXP 3) IS FALSE`
+select 2 REGEXP 3 IS FALSE, 2 REGEXP (3 IS FALSE), (2 REGEXP 3) IS FALSE union select * from v1;
+2 REGEXP 3 IS FALSE 2 REGEXP (3 IS FALSE) (2 REGEXP 3) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 REGEXP 3 COLLATE latin1_bin), charset(2 REGEXP (3 COLLATE latin1_bin)), charset((2 REGEXP 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 regexp 3 collate latin1_bin) AS `charset(2 REGEXP 3 COLLATE latin1_bin)`,charset(2 regexp 3 collate latin1_bin) AS `charset(2 REGEXP (3 COLLATE latin1_bin))`,charset((2 regexp 3) collate latin1_bin) AS `charset((2 REGEXP 3) COLLATE latin1_bin)`
+select charset(2 REGEXP 3 COLLATE latin1_bin), charset(2 REGEXP (3 COLLATE latin1_bin)), charset((2 REGEXP 3) COLLATE latin1_bin) union select * from v1;
+charset(2 REGEXP 3 COLLATE latin1_bin) charset(2 REGEXP (3 COLLATE latin1_bin)) charset((2 REGEXP 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 REGEXP 3 IN (0,1), 2 REGEXP (3 IN (0,1)), (2 REGEXP 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 in (0,1) AS `2 REGEXP 3 IN (0,1)`,2 regexp (3 in (0,1)) AS `2 REGEXP (3 IN (0,1))`,2 regexp 3 in (0,1) AS `(2 REGEXP 3) IN (0,1)`
+select 2 REGEXP 3 IN (0,1), 2 REGEXP (3 IN (0,1)), (2 REGEXP 3) IN (0,1) union select * from v1;
+2 REGEXP 3 IN (0,1) 2 REGEXP (3 IN (0,1)) (2 REGEXP 3) IN (0,1)
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 OR 3, 2 REGEXP (3 OR 3), (2 REGEXP 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 or 3 AS `2 REGEXP 3 OR 3`,2 regexp (3 or 3) AS `2 REGEXP (3 OR 3)`,2 regexp 3 or 3 AS `(2 REGEXP 3) OR 3`
+select 2 REGEXP 3 OR 3, 2 REGEXP (3 OR 3), (2 REGEXP 3) OR 3 union select * from v1;
+2 REGEXP 3 OR 3 2 REGEXP (3 OR 3) (2 REGEXP 3) OR 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 or 3 AS `2 REGEXP 3 || 3`,2 regexp (3 or 3) AS `2 REGEXP (3 || 3)`,2 regexp 3 or 3 AS `(2 REGEXP 3) || 3`
+select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3 union select * from v1;
+2 REGEXP 3 || 3 2 REGEXP (3 || 3) (2 REGEXP 3) || 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 XOR 3, 2 REGEXP (3 XOR 3), (2 REGEXP 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 xor 3 AS `2 REGEXP 3 XOR 3`,2 regexp (3 xor 3) AS `2 REGEXP (3 XOR 3)`,2 regexp 3 xor 3 AS `(2 REGEXP 3) XOR 3`
+select 2 REGEXP 3 XOR 3, 2 REGEXP (3 XOR 3), (2 REGEXP 3) XOR 3 union select * from v1;
+2 REGEXP 3 XOR 3 2 REGEXP (3 XOR 3) (2 REGEXP 3) XOR 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 AND 2, 2 REGEXP (2 AND 2), (2 REGEXP 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 and 2 AS `2 REGEXP 2 AND 2`,2 regexp (2 and 2) AS `2 REGEXP (2 AND 2)`,2 regexp 2 and 2 AS `(2 REGEXP 2) AND 2`
+select 2 REGEXP 2 AND 2, 2 REGEXP (2 AND 2), (2 REGEXP 2) AND 2 union select * from v1;
+2 REGEXP 2 AND 2 2 REGEXP (2 AND 2) (2 REGEXP 2) AND 2
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 && 2, 2 REGEXP (2 && 2), (2 REGEXP 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 and 2 AS `2 REGEXP 2 && 2`,2 regexp (2 and 2) AS `2 REGEXP (2 && 2)`,2 regexp 2 and 2 AS `(2 REGEXP 2) && 2`
+select 2 REGEXP 2 && 2, 2 REGEXP (2 && 2), (2 REGEXP 2) && 2 union select * from v1;
+2 REGEXP 2 && 2 2 REGEXP (2 && 2) (2 REGEXP 2) && 2
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 = 1, 2 REGEXP (2 = 1), (2 REGEXP 2) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 = 1 AS `2 REGEXP 2 = 1`,2 regexp (2 = 1) AS `2 REGEXP (2 = 1)`,2 regexp 2 = 1 AS `(2 REGEXP 2) = 1`
+select 2 REGEXP 2 = 1, 2 REGEXP (2 = 1), (2 REGEXP 2) = 1 union select * from v1;
+2 REGEXP 2 = 1 2 REGEXP (2 = 1) (2 REGEXP 2) = 1
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 <=> 1, 2 REGEXP (2 <=> 1), (2 REGEXP 2) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 <=> 1 AS `2 REGEXP 2 <=> 1`,2 regexp (2 <=> 1) AS `2 REGEXP (2 <=> 1)`,2 regexp 2 <=> 1 AS `(2 REGEXP 2) <=> 1`
+select 2 REGEXP 2 <=> 1, 2 REGEXP (2 <=> 1), (2 REGEXP 2) <=> 1 union select * from v1;
+2 REGEXP 2 <=> 1 2 REGEXP (2 <=> 1) (2 REGEXP 2) <=> 1
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 >= 1, 2 REGEXP (2 >= 1), (2 REGEXP 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 >= 1 AS `2 REGEXP 2 >= 1`,2 regexp (2 >= 1) AS `2 REGEXP (2 >= 1)`,2 regexp 2 >= 1 AS `(2 REGEXP 2) >= 1`
+select 2 REGEXP 2 >= 1, 2 REGEXP (2 >= 1), (2 REGEXP 2) >= 1 union select * from v1;
+2 REGEXP 2 >= 1 2 REGEXP (2 >= 1) (2 REGEXP 2) >= 1
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 <= 3, 2 REGEXP (3 <= 3), (2 REGEXP 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 <= 3 AS `2 REGEXP 3 <= 3`,2 regexp (3 <= 3) AS `2 REGEXP (3 <= 3)`,2 regexp 3 <= 3 AS `(2 REGEXP 3) <= 3`
+select 2 REGEXP 3 <= 3, 2 REGEXP (3 <= 3), (2 REGEXP 3) <= 3 union select * from v1;
+2 REGEXP 3 <= 3 2 REGEXP (3 <= 3) (2 REGEXP 3) <= 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 < 3, 2 REGEXP (3 < 3), (2 REGEXP 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 < 3 AS `2 REGEXP 3 < 3`,2 regexp (3 < 3) AS `2 REGEXP (3 < 3)`,2 regexp 3 < 3 AS `(2 REGEXP 3) < 3`
+select 2 REGEXP 3 < 3, 2 REGEXP (3 < 3), (2 REGEXP 3) < 3 union select * from v1;
+2 REGEXP 3 < 3 2 REGEXP (3 < 3) (2 REGEXP 3) < 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 <> 3, 2 REGEXP (3 <> 3), (2 REGEXP 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 <> 3 AS `2 REGEXP 3 <> 3`,2 regexp (3 <> 3) AS `2 REGEXP (3 <> 3)`,2 regexp 3 <> 3 AS `(2 REGEXP 3) <> 3`
+select 2 REGEXP 3 <> 3, 2 REGEXP (3 <> 3), (2 REGEXP 3) <> 3 union select * from v1;
+2 REGEXP 3 <> 3 2 REGEXP (3 <> 3) (2 REGEXP 3) <> 3
+1 0 1
+create or replace view v1 as select 2 REGEXP 2 > 0, 2 REGEXP (2 > 0), (2 REGEXP 2) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 > 0 AS `2 REGEXP 2 > 0`,2 regexp (2 > 0) AS `2 REGEXP (2 > 0)`,2 regexp 2 > 0 AS `(2 REGEXP 2) > 0`
+select 2 REGEXP 2 > 0, 2 REGEXP (2 > 0), (2 REGEXP 2) > 0 union select * from v1;
+2 REGEXP 2 > 0 2 REGEXP (2 > 0) (2 REGEXP 2) > 0
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 != 3, 2 REGEXP (3 != 3), (2 REGEXP 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 <> 3 AS `2 REGEXP 3 != 3`,2 regexp (3 <> 3) AS `2 REGEXP (3 != 3)`,2 regexp 3 <> 3 AS `(2 REGEXP 3) != 3`
+select 2 REGEXP 3 != 3, 2 REGEXP (3 != 3), (2 REGEXP 3) != 3 union select * from v1;
+2 REGEXP 3 != 3 2 REGEXP (3 != 3) (2 REGEXP 3) != 3
+1 0 1
+create or replace view v1 as select 1 REGEXP 3 LIKE 3, 1 REGEXP (3 LIKE 3), (1 REGEXP 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 regexp 3 like 3 AS `1 REGEXP 3 LIKE 3`,1 regexp (3 like 3) AS `1 REGEXP (3 LIKE 3)`,1 regexp 3 like 3 AS `(1 REGEXP 3) LIKE 3`
+select 1 REGEXP 3 LIKE 3, 1 REGEXP (3 LIKE 3), (1 REGEXP 3) LIKE 3 union select * from v1;
+1 REGEXP 3 LIKE 3 1 REGEXP (3 LIKE 3) (1 REGEXP 3) LIKE 3
+0 1 0
+create or replace view v1 as select 1 REGEXP 3 REGEXP 3, 1 REGEXP (3 REGEXP 3), (1 REGEXP 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 regexp 3 regexp 3 AS `1 REGEXP 3 REGEXP 3`,1 regexp (3 regexp 3) AS `1 REGEXP (3 REGEXP 3)`,1 regexp 3 regexp 3 AS `(1 REGEXP 3) REGEXP 3`
+select 1 REGEXP 3 REGEXP 3, 1 REGEXP (3 REGEXP 3), (1 REGEXP 3) REGEXP 3 union select * from v1;
+1 REGEXP 3 REGEXP 3 1 REGEXP (3 REGEXP 3) (1 REGEXP 3) REGEXP 3
+0 1 0
+create or replace view v1 as select 2 REGEXP 3 | 3, 2 REGEXP (3 | 3), (2 REGEXP 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 | 3 AS `2 REGEXP 3 | 3`,2 regexp 3 | 3 AS `2 REGEXP (3 | 3)`,(2 regexp 3) | 3 AS `(2 REGEXP 3) | 3`
+select 2 REGEXP 3 | 3, 2 REGEXP (3 | 3), (2 REGEXP 3) | 3 union select * from v1;
+2 REGEXP 3 | 3 2 REGEXP (3 | 3) (2 REGEXP 3) | 3
+0 0 3
+create or replace view v1 as select 2 REGEXP 2 & 2, 2 REGEXP (2 & 2), (2 REGEXP 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 & 2 AS `2 REGEXP 2 & 2`,2 regexp 2 & 2 AS `2 REGEXP (2 & 2)`,(2 regexp 2) & 2 AS `(2 REGEXP 2) & 2`
+select 2 REGEXP 2 & 2, 2 REGEXP (2 & 2), (2 REGEXP 2) & 2 union select * from v1;
+2 REGEXP 2 & 2 2 REGEXP (2 & 2) (2 REGEXP 2) & 2
+1 1 0
+create or replace view v1 as select 2 REGEXP 2 << 2, 2 REGEXP (2 << 2), (2 REGEXP 2) << 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 << 2 AS `2 REGEXP 2 << 2`,2 regexp 2 << 2 AS `2 REGEXP (2 << 2)`,(2 regexp 2) << 2 AS `(2 REGEXP 2) << 2`
+select 2 REGEXP 2 << 2, 2 REGEXP (2 << 2), (2 REGEXP 2) << 2 union select * from v1;
+2 REGEXP 2 << 2 2 REGEXP (2 << 2) (2 REGEXP 2) << 2
+0 0 4
+create or replace view v1 as select 2 REGEXP 4 >> 1, 2 REGEXP (4 >> 1), (2 REGEXP 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 4 >> 1 AS `2 REGEXP 4 >> 1`,2 regexp 4 >> 1 AS `2 REGEXP (4 >> 1)`,(2 regexp 4) >> 1 AS `(2 REGEXP 4) >> 1`
+select 2 REGEXP 4 >> 1, 2 REGEXP (4 >> 1), (2 REGEXP 4) >> 1 union select * from v1;
+2 REGEXP 4 >> 1 2 REGEXP (4 >> 1) (2 REGEXP 4) >> 1
+1 1 0
+create or replace view v1 as select 2 REGEXP '2000-01-01' +INTERVAL 1 DAY, 2 REGEXP ('2000-01-01' +INTERVAL 1 DAY), (2 REGEXP '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp '2000-01-01' + interval 1 day AS `2 REGEXP '2000-01-01' +INTERVAL 1 DAY`,2 regexp '2000-01-01' + interval 1 day AS `2 REGEXP ('2000-01-01' +INTERVAL 1 DAY)`,(2 regexp '2000-01-01') + interval 1 day AS `(2 REGEXP '2000-01-01') +INTERVAL 1 DAY`
+select 2 REGEXP '2000-01-01' +INTERVAL 1 DAY, 2 REGEXP ('2000-01-01' +INTERVAL 1 DAY), (2 REGEXP '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 REGEXP '2000-01-01' +INTERVAL 1 DAY 2 REGEXP ('2000-01-01' +INTERVAL 1 DAY) (2 REGEXP '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 REGEXP 3 + 3, 2 REGEXP (3 + 3), (2 REGEXP 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 + 3 AS `2 REGEXP 3 + 3`,2 regexp 3 + 3 AS `2 REGEXP (3 + 3)`,(2 regexp 3) + 3 AS `(2 REGEXP 3) + 3`
+select 2 REGEXP 3 + 3, 2 REGEXP (3 + 3), (2 REGEXP 3) + 3 union select * from v1;
+2 REGEXP 3 + 3 2 REGEXP (3 + 3) (2 REGEXP 3) + 3
+0 0 3
+create or replace view v1 as select 2 REGEXP 3 - 3, 2 REGEXP (3 - 3), (2 REGEXP 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 - 3 AS `2 REGEXP 3 - 3`,2 regexp 3 - 3 AS `2 REGEXP (3 - 3)`,(2 regexp 3) - 3 AS `(2 REGEXP 3) - 3`
+select 2 REGEXP 3 - 3, 2 REGEXP (3 - 3), (2 REGEXP 3) - 3 union select * from v1;
+2 REGEXP 3 - 3 2 REGEXP (3 - 3) (2 REGEXP 3) - 3
+0 0 -3
+create or replace view v1 as select 2 REGEXP 2 * 2, 2 REGEXP (2 * 2), (2 REGEXP 2) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 * 2 AS `2 REGEXP 2 * 2`,2 regexp 2 * 2 AS `2 REGEXP (2 * 2)`,(2 regexp 2) * 2 AS `(2 REGEXP 2) * 2`
+select 2 REGEXP 2 * 2, 2 REGEXP (2 * 2), (2 REGEXP 2) * 2 union select * from v1;
+2 REGEXP 2 * 2 2 REGEXP (2 * 2) (2 REGEXP 2) * 2
+0 0 2
+create or replace view v1 as select 2 REGEXP 2 / 2, 2 REGEXP (2 / 2), (2 REGEXP 2) / 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 / 2 AS `2 REGEXP 2 / 2`,2 regexp 2 / 2 AS `2 REGEXP (2 / 2)`,(2 regexp 2) / 2 AS `(2 REGEXP 2) / 2`
+select 2 REGEXP 2 / 2, 2 REGEXP (2 / 2), (2 REGEXP 2) / 2 union select * from v1;
+2 REGEXP 2 / 2 2 REGEXP (2 / 2) (2 REGEXP 2) / 2
+0 0 0.5000
+create or replace view v1 as select 2 REGEXP 4 DIV 2, 2 REGEXP (4 DIV 2), (2 REGEXP 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 4 DIV 2 AS `2 REGEXP 4 DIV 2`,2 regexp 4 DIV 2 AS `2 REGEXP (4 DIV 2)`,(2 regexp 4) DIV 2 AS `(2 REGEXP 4) DIV 2`
+select 2 REGEXP 4 DIV 2, 2 REGEXP (4 DIV 2), (2 REGEXP 4) DIV 2 union select * from v1;
+2 REGEXP 4 DIV 2 2 REGEXP (4 DIV 2) (2 REGEXP 4) DIV 2
+1 1 0
+create or replace view v1 as select 2 REGEXP 2 MOD 2, 2 REGEXP (2 MOD 2), (2 REGEXP 2) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 MOD 2 AS `2 REGEXP 2 MOD 2`,2 regexp 2 MOD 2 AS `2 REGEXP (2 MOD 2)`,(2 regexp 2) MOD 2 AS `(2 REGEXP 2) MOD 2`
+select 2 REGEXP 2 MOD 2, 2 REGEXP (2 MOD 2), (2 REGEXP 2) MOD 2 union select * from v1;
+2 REGEXP 2 MOD 2 2 REGEXP (2 MOD 2) (2 REGEXP 2) MOD 2
+0 0 1
+create or replace view v1 as select 2 REGEXP 2 % 2, 2 REGEXP (2 % 2), (2 REGEXP 2) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 MOD 2 AS `2 REGEXP 2 % 2`,2 regexp 2 MOD 2 AS `2 REGEXP (2 % 2)`,(2 regexp 2) MOD 2 AS `(2 REGEXP 2) % 2`
+select 2 REGEXP 2 % 2, 2 REGEXP (2 % 2), (2 REGEXP 2) % 2 union select * from v1;
+2 REGEXP 2 % 2 2 REGEXP (2 % 2) (2 REGEXP 2) % 2
+0 0 1
+create or replace view v1 as select 2 REGEXP 3 ^ 3, 2 REGEXP (3 ^ 3), (2 REGEXP 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 ^ 3 AS `2 REGEXP 3 ^ 3`,2 regexp 3 ^ 3 AS `2 REGEXP (3 ^ 3)`,(2 regexp 3) ^ 3 AS `(2 REGEXP 3) ^ 3`
+select 2 REGEXP 3 ^ 3, 2 REGEXP (3 ^ 3), (2 REGEXP 3) ^ 3 union select * from v1;
+2 REGEXP 3 ^ 3 2 REGEXP (3 ^ 3) (2 REGEXP 3) ^ 3
+0 0 3
+create or replace view v1 as select 2 REGEXP 2 BETWEEN 1 AND 3, 2 REGEXP (2 BETWEEN 1 AND 3), (2 REGEXP 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 2 between 1 and 3 AS `2 REGEXP 2 BETWEEN 1 AND 3`,2 regexp (2 between 1 and 3) AS `2 REGEXP (2 BETWEEN 1 AND 3)`,2 regexp 2 between 1 and 3 AS `(2 REGEXP 2) BETWEEN 1 AND 3`
+select 2 REGEXP 2 BETWEEN 1 AND 3, 2 REGEXP (2 BETWEEN 1 AND 3), (2 REGEXP 2) BETWEEN 1 AND 3 union select * from v1;
+2 REGEXP 2 BETWEEN 1 AND 3 2 REGEXP (2 BETWEEN 1 AND 3) (2 REGEXP 2) BETWEEN 1 AND 3
+1 0 1
+create or replace view v1 as select 2 | 3 IS FALSE, 2 | (3 IS FALSE), (2 | 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 is false AS `2 | 3 IS FALSE`,2 | (3 is false) AS `2 | (3 IS FALSE)`,2 | 3 is false AS `(2 | 3) IS FALSE`
+select 2 | 3 IS FALSE, 2 | (3 IS FALSE), (2 | 3) IS FALSE union select * from v1;
+2 | 3 IS FALSE 2 | (3 IS FALSE) (2 | 3) IS FALSE
+0 2 0
+create or replace view v1 as select charset(2 | 3 COLLATE latin1_bin), charset(2 | (3 COLLATE latin1_bin)), charset((2 | 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 | 3 collate latin1_bin) AS `charset(2 | 3 COLLATE latin1_bin)`,charset(2 | 3 collate latin1_bin) AS `charset(2 | (3 COLLATE latin1_bin))`,charset((2 | 3) collate latin1_bin) AS `charset((2 | 3) COLLATE latin1_bin)`
+select charset(2 | 3 COLLATE latin1_bin), charset(2 | (3 COLLATE latin1_bin)), charset((2 | 3) COLLATE latin1_bin) union select * from v1;
+charset(2 | 3 COLLATE latin1_bin) charset(2 | (3 COLLATE latin1_bin)) charset((2 | 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 | 3 IN (0,1), 2 | (3 IN (0,1)), (2 | 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 in (0,1) AS `2 | 3 IN (0,1)`,2 | (3 in (0,1)) AS `2 | (3 IN (0,1))`,2 | 3 in (0,1) AS `(2 | 3) IN (0,1)`
+select 2 | 3 IN (0,1), 2 | (3 IN (0,1)), (2 | 3) IN (0,1) union select * from v1;
+2 | 3 IN (0,1) 2 | (3 IN (0,1)) (2 | 3) IN (0,1)
+0 2 0
+create or replace view v1 as select 2 | 3 OR 3, 2 | (3 OR 3), (2 | 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 or 3 AS `2 | 3 OR 3`,2 | (3 or 3) AS `2 | (3 OR 3)`,2 | 3 or 3 AS `(2 | 3) OR 3`
+select 2 | 3 OR 3, 2 | (3 OR 3), (2 | 3) OR 3 union select * from v1;
+2 | 3 OR 3 2 | (3 OR 3) (2 | 3) OR 3
+1 3 1
+create or replace view v1 as select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 or 3 AS `2 | 3 || 3`,2 | (3 or 3) AS `2 | (3 || 3)`,2 | 3 or 3 AS `(2 | 3) || 3`
+select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3 union select * from v1;
+2 | 3 || 3 2 | (3 || 3) (2 | 3) || 3
+1 3 1
+create or replace view v1 as select 2 | 3 XOR 3, 2 | (3 XOR 3), (2 | 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 xor 3 AS `2 | 3 XOR 3`,2 | (3 xor 3) AS `2 | (3 XOR 3)`,2 | 3 xor 3 AS `(2 | 3) XOR 3`
+select 2 | 3 XOR 3, 2 | (3 XOR 3), (2 | 3) XOR 3 union select * from v1;
+2 | 3 XOR 3 2 | (3 XOR 3) (2 | 3) XOR 3
+0 2 0
+create or replace view v1 as select 2 | 3 AND 3, 2 | (3 AND 3), (2 | 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 and 3 AS `2 | 3 AND 3`,2 | (3 and 3) AS `2 | (3 AND 3)`,2 | 3 and 3 AS `(2 | 3) AND 3`
+select 2 | 3 AND 3, 2 | (3 AND 3), (2 | 3) AND 3 union select * from v1;
+2 | 3 AND 3 2 | (3 AND 3) (2 | 3) AND 3
+1 3 1
+create or replace view v1 as select 2 | 3 && 3, 2 | (3 && 3), (2 | 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 and 3 AS `2 | 3 && 3`,2 | (3 and 3) AS `2 | (3 && 3)`,2 | 3 and 3 AS `(2 | 3) && 3`
+select 2 | 3 && 3, 2 | (3 && 3), (2 | 3) && 3 union select * from v1;
+2 | 3 && 3 2 | (3 && 3) (2 | 3) && 3
+1 3 1
+create or replace view v1 as select 2 | 3 = 3, 2 | (3 = 3), (2 | 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 = 3 AS `2 | 3 = 3`,2 | (3 = 3) AS `2 | (3 = 3)`,2 | 3 = 3 AS `(2 | 3) = 3`
+select 2 | 3 = 3, 2 | (3 = 3), (2 | 3) = 3 union select * from v1;
+2 | 3 = 3 2 | (3 = 3) (2 | 3) = 3
+1 3 1
+create or replace view v1 as select 2 | 3 <=> 3, 2 | (3 <=> 3), (2 | 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 <=> 3 AS `2 | 3 <=> 3`,2 | (3 <=> 3) AS `2 | (3 <=> 3)`,2 | 3 <=> 3 AS `(2 | 3) <=> 3`
+select 2 | 3 <=> 3, 2 | (3 <=> 3), (2 | 3) <=> 3 union select * from v1;
+2 | 3 <=> 3 2 | (3 <=> 3) (2 | 3) <=> 3
+1 3 1
+create or replace view v1 as select 2 | 3 >= 3, 2 | (3 >= 3), (2 | 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 >= 3 AS `2 | 3 >= 3`,2 | (3 >= 3) AS `2 | (3 >= 3)`,2 | 3 >= 3 AS `(2 | 3) >= 3`
+select 2 | 3 >= 3, 2 | (3 >= 3), (2 | 3) >= 3 union select * from v1;
+2 | 3 >= 3 2 | (3 >= 3) (2 | 3) >= 3
+1 3 1
+create or replace view v1 as select 2 | 3 <= 3, 2 | (3 <= 3), (2 | 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 <= 3 AS `2 | 3 <= 3`,2 | (3 <= 3) AS `2 | (3 <= 3)`,2 | 3 <= 3 AS `(2 | 3) <= 3`
+select 2 | 3 <= 3, 2 | (3 <= 3), (2 | 3) <= 3 union select * from v1;
+2 | 3 <= 3 2 | (3 <= 3) (2 | 3) <= 3
+1 3 1
+create or replace view v1 as select 2 | 3 < 3, 2 | (3 < 3), (2 | 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 < 3 AS `2 | 3 < 3`,2 | (3 < 3) AS `2 | (3 < 3)`,2 | 3 < 3 AS `(2 | 3) < 3`
+select 2 | 3 < 3, 2 | (3 < 3), (2 | 3) < 3 union select * from v1;
+2 | 3 < 3 2 | (3 < 3) (2 | 3) < 3
+0 2 0
+create or replace view v1 as select 2 | 3 <> 3, 2 | (3 <> 3), (2 | 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 <> 3 AS `2 | 3 <> 3`,2 | (3 <> 3) AS `2 | (3 <> 3)`,2 | 3 <> 3 AS `(2 | 3) <> 3`
+select 2 | 3 <> 3, 2 | (3 <> 3), (2 | 3) <> 3 union select * from v1;
+2 | 3 <> 3 2 | (3 <> 3) (2 | 3) <> 3
+0 2 0
+create or replace view v1 as select 2 | 3 > 3, 2 | (3 > 3), (2 | 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 > 3 AS `2 | 3 > 3`,2 | (3 > 3) AS `2 | (3 > 3)`,2 | 3 > 3 AS `(2 | 3) > 3`
+select 2 | 3 > 3, 2 | (3 > 3), (2 | 3) > 3 union select * from v1;
+2 | 3 > 3 2 | (3 > 3) (2 | 3) > 3
+0 2 0
+create or replace view v1 as select 2 | 3 != 3, 2 | (3 != 3), (2 | 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 <> 3 AS `2 | 3 != 3`,2 | (3 <> 3) AS `2 | (3 != 3)`,2 | 3 <> 3 AS `(2 | 3) != 3`
+select 2 | 3 != 3, 2 | (3 != 3), (2 | 3) != 3 union select * from v1;
+2 | 3 != 3 2 | (3 != 3) (2 | 3) != 3
+0 2 0
+create or replace view v1 as select 2 | 3 LIKE 3, 2 | (3 LIKE 3), (2 | 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 like 3 AS `2 | 3 LIKE 3`,2 | (3 like 3) AS `2 | (3 LIKE 3)`,2 | 3 like 3 AS `(2 | 3) LIKE 3`
+select 2 | 3 LIKE 3, 2 | (3 LIKE 3), (2 | 3) LIKE 3 union select * from v1;
+2 | 3 LIKE 3 2 | (3 LIKE 3) (2 | 3) LIKE 3
+1 3 1
+create or replace view v1 as select 2 | 3 REGEXP 3, 2 | (3 REGEXP 3), (2 | 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 regexp 3 AS `2 | 3 REGEXP 3`,2 | (3 regexp 3) AS `2 | (3 REGEXP 3)`,2 | 3 regexp 3 AS `(2 | 3) REGEXP 3`
+select 2 | 3 REGEXP 3, 2 | (3 REGEXP 3), (2 | 3) REGEXP 3 union select * from v1;
+2 | 3 REGEXP 3 2 | (3 REGEXP 3) (2 | 3) REGEXP 3
+1 3 1
+create or replace view v1 as select 2 | 0 & 0, 2 | (0 & 0), (2 | 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 0 & 0 AS `2 | 0 & 0`,2 | 0 & 0 AS `2 | (0 & 0)`,(2 | 0) & 0 AS `(2 | 0) & 0`
+select 2 | 0 & 0, 2 | (0 & 0), (2 | 0) & 0 union select * from v1;
+2 | 0 & 0 2 | (0 & 0) (2 | 0) & 0
+2 2 0
+create or replace view v1 as select 2 | 3 << 3, 2 | (3 << 3), (2 | 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 << 3 AS `2 | 3 << 3`,2 | 3 << 3 AS `2 | (3 << 3)`,(2 | 3) << 3 AS `(2 | 3) << 3`
+select 2 | 3 << 3, 2 | (3 << 3), (2 | 3) << 3 union select * from v1;
+2 | 3 << 3 2 | (3 << 3) (2 | 3) << 3
+26 26 24
+create or replace view v1 as select 2 | 3 >> 3, 2 | (3 >> 3), (2 | 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 >> 3 AS `2 | 3 >> 3`,2 | 3 >> 3 AS `2 | (3 >> 3)`,(2 | 3) >> 3 AS `(2 | 3) >> 3`
+select 2 | 3 >> 3, 2 | (3 >> 3), (2 | 3) >> 3 union select * from v1;
+2 | 3 >> 3 2 | (3 >> 3) (2 | 3) >> 3
+2 2 0
+create or replace view v1 as select 2 | '2000-01-01' +INTERVAL 1 DAY, 2 | ('2000-01-01' +INTERVAL 1 DAY), (2 | '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | '2000-01-01' + interval 1 day AS `2 | '2000-01-01' +INTERVAL 1 DAY`,2 | '2000-01-01' + interval 1 day AS `2 | ('2000-01-01' +INTERVAL 1 DAY)`,(2 | '2000-01-01') + interval 1 day AS `(2 | '2000-01-01') +INTERVAL 1 DAY`
+select 2 | '2000-01-01' +INTERVAL 1 DAY, 2 | ('2000-01-01' +INTERVAL 1 DAY), (2 | '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 | '2000-01-01' +INTERVAL 1 DAY 2 | ('2000-01-01' +INTERVAL 1 DAY) (2 | '2000-01-01') +INTERVAL 1 DAY
+20000102 20000102 NULL
+create or replace view v1 as select 2 | 1 + 1, 2 | (1 + 1), (2 | 1) + 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 1 + 1 AS `2 | 1 + 1`,2 | 1 + 1 AS `2 | (1 + 1)`,(2 | 1) + 1 AS `(2 | 1) + 1`
+select 2 | 1 + 1, 2 | (1 + 1), (2 | 1) + 1 union select * from v1;
+2 | 1 + 1 2 | (1 + 1) (2 | 1) + 1
+2 2 4
+create or replace view v1 as select 2 | 3 - 3, 2 | (3 - 3), (2 | 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 - 3 AS `2 | 3 - 3`,2 | 3 - 3 AS `2 | (3 - 3)`,(2 | 3) - 3 AS `(2 | 3) - 3`
+select 2 | 3 - 3, 2 | (3 - 3), (2 | 3) - 3 union select * from v1;
+2 | 3 - 3 2 | (3 - 3) (2 | 3) - 3
+2 2 0
+create or replace view v1 as select 2 | 3 * 3, 2 | (3 * 3), (2 | 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 * 3 AS `2 | 3 * 3`,2 | 3 * 3 AS `2 | (3 * 3)`,(2 | 3) * 3 AS `(2 | 3) * 3`
+select 2 | 3 * 3, 2 | (3 * 3), (2 | 3) * 3 union select * from v1;
+2 | 3 * 3 2 | (3 * 3) (2 | 3) * 3
+11 11 9
+create or replace view v1 as select 2 | 3 / 3, 2 | (3 / 3), (2 | 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 / 3 AS `2 | 3 / 3`,2 | 3 / 3 AS `2 | (3 / 3)`,(2 | 3) / 3 AS `(2 | 3) / 3`
+select 2 | 3 / 3, 2 | (3 / 3), (2 | 3) / 3 union select * from v1;
+2 | 3 / 3 2 | (3 / 3) (2 | 3) / 3
+3 3 1.0000
+create or replace view v1 as select 2 | 3 DIV 3, 2 | (3 DIV 3), (2 | 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 DIV 3 AS `2 | 3 DIV 3`,2 | 3 DIV 3 AS `2 | (3 DIV 3)`,(2 | 3) DIV 3 AS `(2 | 3) DIV 3`
+select 2 | 3 DIV 3, 2 | (3 DIV 3), (2 | 3) DIV 3 union select * from v1;
+2 | 3 DIV 3 2 | (3 DIV 3) (2 | 3) DIV 3
+3 3 1
+create or replace view v1 as select 2 | 3 MOD 3, 2 | (3 MOD 3), (2 | 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 MOD 3 AS `2 | 3 MOD 3`,2 | 3 MOD 3 AS `2 | (3 MOD 3)`,(2 | 3) MOD 3 AS `(2 | 3) MOD 3`
+select 2 | 3 MOD 3, 2 | (3 MOD 3), (2 | 3) MOD 3 union select * from v1;
+2 | 3 MOD 3 2 | (3 MOD 3) (2 | 3) MOD 3
+2 2 0
+create or replace view v1 as select 2 | 3 % 3, 2 | (3 % 3), (2 | 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 MOD 3 AS `2 | 3 % 3`,2 | 3 MOD 3 AS `2 | (3 % 3)`,(2 | 3) MOD 3 AS `(2 | 3) % 3`
+select 2 | 3 % 3, 2 | (3 % 3), (2 | 3) % 3 union select * from v1;
+2 | 3 % 3 2 | (3 % 3) (2 | 3) % 3
+2 2 0
+create or replace view v1 as select 2 | 3 ^ 3, 2 | (3 ^ 3), (2 | 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 ^ 3 AS `2 | 3 ^ 3`,2 | 3 ^ 3 AS `2 | (3 ^ 3)`,(2 | 3) ^ 3 AS `(2 | 3) ^ 3`
+select 2 | 3 ^ 3, 2 | (3 ^ 3), (2 | 3) ^ 3 union select * from v1;
+2 | 3 ^ 3 2 | (3 ^ 3) (2 | 3) ^ 3
+2 2 0
+create or replace view v1 as select 2 | 3 BETWEEN 1 AND 3, 2 | (3 BETWEEN 1 AND 3), (2 | 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 between 1 and 3 AS `2 | 3 BETWEEN 1 AND 3`,2 | (3 between 1 and 3) AS `2 | (3 BETWEEN 1 AND 3)`,2 | 3 between 1 and 3 AS `(2 | 3) BETWEEN 1 AND 3`
+select 2 | 3 BETWEEN 1 AND 3, 2 | (3 BETWEEN 1 AND 3), (2 | 3) BETWEEN 1 AND 3 union select * from v1;
+2 | 3 BETWEEN 1 AND 3 2 | (3 BETWEEN 1 AND 3) (2 | 3) BETWEEN 1 AND 3
+1 3 1
+create or replace view v1 as select 2 & 1 IS FALSE, 2 & (1 IS FALSE), (2 & 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 1 is false AS `2 & 1 IS FALSE`,2 & (1 is false) AS `2 & (1 IS FALSE)`,2 & 1 is false AS `(2 & 1) IS FALSE`
+select 2 & 1 IS FALSE, 2 & (1 IS FALSE), (2 & 1) IS FALSE union select * from v1;
+2 & 1 IS FALSE 2 & (1 IS FALSE) (2 & 1) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 & 3 COLLATE latin1_bin), charset(2 & (3 COLLATE latin1_bin)), charset((2 & 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 & 3 collate latin1_bin) AS `charset(2 & 3 COLLATE latin1_bin)`,charset(2 & 3 collate latin1_bin) AS `charset(2 & (3 COLLATE latin1_bin))`,charset((2 & 3) collate latin1_bin) AS `charset((2 & 3) COLLATE latin1_bin)`
+select charset(2 & 3 COLLATE latin1_bin), charset(2 & (3 COLLATE latin1_bin)), charset((2 & 3) COLLATE latin1_bin) union select * from v1;
+charset(2 & 3 COLLATE latin1_bin) charset(2 & (3 COLLATE latin1_bin)) charset((2 & 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 & 4 IN (0,1), 2 & (4 IN (0,1)), (2 & 4) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 4 in (0,1) AS `2 & 4 IN (0,1)`,2 & (4 in (0,1)) AS `2 & (4 IN (0,1))`,2 & 4 in (0,1) AS `(2 & 4) IN (0,1)`
+select 2 & 4 IN (0,1), 2 & (4 IN (0,1)), (2 & 4) IN (0,1) union select * from v1;
+2 & 4 IN (0,1) 2 & (4 IN (0,1)) (2 & 4) IN (0,1)
+1 0 1
+create or replace view v1 as select 2 & 3 OR 3, 2 & (3 OR 3), (2 & 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 or 3 AS `2 & 3 OR 3`,2 & (3 or 3) AS `2 & (3 OR 3)`,2 & 3 or 3 AS `(2 & 3) OR 3`
+select 2 & 3 OR 3, 2 & (3 OR 3), (2 & 3) OR 3 union select * from v1;
+2 & 3 OR 3 2 & (3 OR 3) (2 & 3) OR 3
+1 0 1
+create or replace view v1 as select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 or 3 AS `2 & 3 || 3`,2 & (3 or 3) AS `2 & (3 || 3)`,2 & 3 or 3 AS `(2 & 3) || 3`
+select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3 union select * from v1;
+2 & 3 || 3 2 & (3 || 3) (2 & 3) || 3
+1 0 1
+create or replace view v1 as select 2 & 1 XOR 1, 2 & (1 XOR 1), (2 & 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 1 xor 1 AS `2 & 1 XOR 1`,2 & (1 xor 1) AS `2 & (1 XOR 1)`,2 & 1 xor 1 AS `(2 & 1) XOR 1`
+select 2 & 1 XOR 1, 2 & (1 XOR 1), (2 & 1) XOR 1 union select * from v1;
+2 & 1 XOR 1 2 & (1 XOR 1) (2 & 1) XOR 1
+1 0 1
+create or replace view v1 as select 2 & 3 AND 3, 2 & (3 AND 3), (2 & 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 and 3 AS `2 & 3 AND 3`,2 & (3 and 3) AS `2 & (3 AND 3)`,2 & 3 and 3 AS `(2 & 3) AND 3`
+select 2 & 3 AND 3, 2 & (3 AND 3), (2 & 3) AND 3 union select * from v1;
+2 & 3 AND 3 2 & (3 AND 3) (2 & 3) AND 3
+1 0 1
+create or replace view v1 as select 2 & 3 && 3, 2 & (3 && 3), (2 & 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 and 3 AS `2 & 3 && 3`,2 & (3 and 3) AS `2 & (3 && 3)`,2 & 3 and 3 AS `(2 & 3) && 3`
+select 2 & 3 && 3, 2 & (3 && 3), (2 & 3) && 3 union select * from v1;
+2 & 3 && 3 2 & (3 && 3) (2 & 3) && 3
+1 0 1
+create or replace view v1 as select 2 & 3 = 2, 2 & (3 = 2), (2 & 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 = 2 AS `2 & 3 = 2`,2 & (3 = 2) AS `2 & (3 = 2)`,2 & 3 = 2 AS `(2 & 3) = 2`
+select 2 & 3 = 2, 2 & (3 = 2), (2 & 3) = 2 union select * from v1;
+2 & 3 = 2 2 & (3 = 2) (2 & 3) = 2
+1 0 1
+create or replace view v1 as select 2 & 3 <=> 2, 2 & (3 <=> 2), (2 & 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 <=> 2 AS `2 & 3 <=> 2`,2 & (3 <=> 2) AS `2 & (3 <=> 2)`,2 & 3 <=> 2 AS `(2 & 3) <=> 2`
+select 2 & 3 <=> 2, 2 & (3 <=> 2), (2 & 3) <=> 2 union select * from v1;
+2 & 3 <=> 2 2 & (3 <=> 2) (2 & 3) <=> 2
+1 0 1
+create or replace view v1 as select 2 & 3 >= 2, 2 & (3 >= 2), (2 & 3) >= 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 >= 2 AS `2 & 3 >= 2`,2 & (3 >= 2) AS `2 & (3 >= 2)`,2 & 3 >= 2 AS `(2 & 3) >= 2`
+select 2 & 3 >= 2, 2 & (3 >= 2), (2 & 3) >= 2 union select * from v1;
+2 & 3 >= 2 2 & (3 >= 2) (2 & 3) >= 2
+1 0 1
+create or replace view v1 as select 2 & 3 <= 3, 2 & (3 <= 3), (2 & 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 <= 3 AS `2 & 3 <= 3`,2 & (3 <= 3) AS `2 & (3 <= 3)`,2 & 3 <= 3 AS `(2 & 3) <= 3`
+select 2 & 3 <= 3, 2 & (3 <= 3), (2 & 3) <= 3 union select * from v1;
+2 & 3 <= 3 2 & (3 <= 3) (2 & 3) <= 3
+1 0 1
+create or replace view v1 as select 2 & 3 < 3, 2 & (3 < 3), (2 & 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 < 3 AS `2 & 3 < 3`,2 & (3 < 3) AS `2 & (3 < 3)`,2 & 3 < 3 AS `(2 & 3) < 3`
+select 2 & 3 < 3, 2 & (3 < 3), (2 & 3) < 3 union select * from v1;
+2 & 3 < 3 2 & (3 < 3) (2 & 3) < 3
+1 0 1
+create or replace view v1 as select 2 & 3 <> 3, 2 & (3 <> 3), (2 & 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 <> 3 AS `2 & 3 <> 3`,2 & (3 <> 3) AS `2 & (3 <> 3)`,2 & 3 <> 3 AS `(2 & 3) <> 3`
+select 2 & 3 <> 3, 2 & (3 <> 3), (2 & 3) <> 3 union select * from v1;
+2 & 3 <> 3 2 & (3 <> 3) (2 & 3) <> 3
+1 0 1
+create or replace view v1 as select 2 & 3 > 1, 2 & (3 > 1), (2 & 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 > 1 AS `2 & 3 > 1`,2 & (3 > 1) AS `2 & (3 > 1)`,2 & 3 > 1 AS `(2 & 3) > 1`
+select 2 & 3 > 1, 2 & (3 > 1), (2 & 3) > 1 union select * from v1;
+2 & 3 > 1 2 & (3 > 1) (2 & 3) > 1
+1 0 1
+create or replace view v1 as select 2 & 3 != 3, 2 & (3 != 3), (2 & 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 <> 3 AS `2 & 3 != 3`,2 & (3 <> 3) AS `2 & (3 != 3)`,2 & 3 <> 3 AS `(2 & 3) != 3`
+select 2 & 3 != 3, 2 & (3 != 3), (2 & 3) != 3 union select * from v1;
+2 & 3 != 3 2 & (3 != 3) (2 & 3) != 3
+1 0 1
+create or replace view v1 as select 2 & 3 LIKE 2, 2 & (3 LIKE 2), (2 & 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 like 2 AS `2 & 3 LIKE 2`,2 & (3 like 2) AS `2 & (3 LIKE 2)`,2 & 3 like 2 AS `(2 & 3) LIKE 2`
+select 2 & 3 LIKE 2, 2 & (3 LIKE 2), (2 & 3) LIKE 2 union select * from v1;
+2 & 3 LIKE 2 2 & (3 LIKE 2) (2 & 3) LIKE 2
+1 0 1
+create or replace view v1 as select 2 & 3 REGEXP 2, 2 & (3 REGEXP 2), (2 & 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 regexp 2 AS `2 & 3 REGEXP 2`,2 & (3 regexp 2) AS `2 & (3 REGEXP 2)`,2 & 3 regexp 2 AS `(2 & 3) REGEXP 2`
+select 2 & 3 REGEXP 2, 2 & (3 REGEXP 2), (2 & 3) REGEXP 2 union select * from v1;
+2 & 3 REGEXP 2 2 & (3 REGEXP 2) (2 & 3) REGEXP 2
+1 0 1
+create or replace view v1 as select 2 & 3 | 3, 2 & (3 | 3), (2 & 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 | 3 AS `2 & 3 | 3`,2 & (3 | 3) AS `2 & (3 | 3)`,2 & 3 | 3 AS `(2 & 3) | 3`
+select 2 & 3 | 3, 2 & (3 | 3), (2 & 3) | 3 union select * from v1;
+2 & 3 | 3 2 & (3 | 3) (2 & 3) | 3
+3 2 3
+create or replace view v1 as select 2 & 3 << 3, 2 & (3 << 3), (2 & 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 << 3 AS `2 & 3 << 3`,2 & 3 << 3 AS `2 & (3 << 3)`,(2 & 3) << 3 AS `(2 & 3) << 3`
+select 2 & 3 << 3, 2 & (3 << 3), (2 & 3) << 3 union select * from v1;
+2 & 3 << 3 2 & (3 << 3) (2 & 3) << 3
+0 0 16
+create or replace view v1 as select 2 & 3 >> 1, 2 & (3 >> 1), (2 & 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 >> 1 AS `2 & 3 >> 1`,2 & 3 >> 1 AS `2 & (3 >> 1)`,(2 & 3) >> 1 AS `(2 & 3) >> 1`
+select 2 & 3 >> 1, 2 & (3 >> 1), (2 & 3) >> 1 union select * from v1;
+2 & 3 >> 1 2 & (3 >> 1) (2 & 3) >> 1
+0 0 1
+create or replace view v1 as select 2 & '2000-01-01' +INTERVAL 1 DAY, 2 & ('2000-01-01' +INTERVAL 1 DAY), (2 & '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & '2000-01-01' + interval 1 day AS `2 & '2000-01-01' +INTERVAL 1 DAY`,2 & '2000-01-01' + interval 1 day AS `2 & ('2000-01-01' +INTERVAL 1 DAY)`,(2 & '2000-01-01') + interval 1 day AS `(2 & '2000-01-01') +INTERVAL 1 DAY`
+select 2 & '2000-01-01' +INTERVAL 1 DAY, 2 & ('2000-01-01' +INTERVAL 1 DAY), (2 & '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 & '2000-01-01' +INTERVAL 1 DAY 2 & ('2000-01-01' +INTERVAL 1 DAY) (2 & '2000-01-01') +INTERVAL 1 DAY
+2 2 NULL
+create or replace view v1 as select 2 & 3 + 3, 2 & (3 + 3), (2 & 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 + 3 AS `2 & 3 + 3`,2 & 3 + 3 AS `2 & (3 + 3)`,(2 & 3) + 3 AS `(2 & 3) + 3`
+select 2 & 3 + 3, 2 & (3 + 3), (2 & 3) + 3 union select * from v1;
+2 & 3 + 3 2 & (3 + 3) (2 & 3) + 3
+2 2 5
+create or replace view v1 as select 6 & 4 - 3, 6 & (4 - 3), (6 & 4) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 6 & 4 - 3 AS `6 & 4 - 3`,6 & 4 - 3 AS `6 & (4 - 3)`,(6 & 4) - 3 AS `(6 & 4) - 3`
+select 6 & 4 - 3, 6 & (4 - 3), (6 & 4) - 3 union select * from v1;
+6 & 4 - 3 6 & (4 - 3) (6 & 4) - 3
+0 0 1
+create or replace view v1 as select 2 & 3 * 3, 2 & (3 * 3), (2 & 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 * 3 AS `2 & 3 * 3`,2 & 3 * 3 AS `2 & (3 * 3)`,(2 & 3) * 3 AS `(2 & 3) * 3`
+select 2 & 3 * 3, 2 & (3 * 3), (2 & 3) * 3 union select * from v1;
+2 & 3 * 3 2 & (3 * 3) (2 & 3) * 3
+0 0 6
+create or replace view v1 as select 2 & 3 / 3, 2 & (3 / 3), (2 & 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 / 3 AS `2 & 3 / 3`,2 & 3 / 3 AS `2 & (3 / 3)`,(2 & 3) / 3 AS `(2 & 3) / 3`
+select 2 & 3 / 3, 2 & (3 / 3), (2 & 3) / 3 union select * from v1;
+2 & 3 / 3 2 & (3 / 3) (2 & 3) / 3
+0 0 0.6667
+create or replace view v1 as select 2 & 3 DIV 2, 2 & (3 DIV 2), (2 & 3) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 DIV 2 AS `2 & 3 DIV 2`,2 & 3 DIV 2 AS `2 & (3 DIV 2)`,(2 & 3) DIV 2 AS `(2 & 3) DIV 2`
+select 2 & 3 DIV 2, 2 & (3 DIV 2), (2 & 3) DIV 2 union select * from v1;
+2 & 3 DIV 2 2 & (3 DIV 2) (2 & 3) DIV 2
+0 0 1
+create or replace view v1 as select 2 & 3 MOD 3, 2 & (3 MOD 3), (2 & 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 MOD 3 AS `2 & 3 MOD 3`,2 & 3 MOD 3 AS `2 & (3 MOD 3)`,(2 & 3) MOD 3 AS `(2 & 3) MOD 3`
+select 2 & 3 MOD 3, 2 & (3 MOD 3), (2 & 3) MOD 3 union select * from v1;
+2 & 3 MOD 3 2 & (3 MOD 3) (2 & 3) MOD 3
+0 0 2
+create or replace view v1 as select 2 & 3 % 3, 2 & (3 % 3), (2 & 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 MOD 3 AS `2 & 3 % 3`,2 & 3 MOD 3 AS `2 & (3 % 3)`,(2 & 3) MOD 3 AS `(2 & 3) % 3`
+select 2 & 3 % 3, 2 & (3 % 3), (2 & 3) % 3 union select * from v1;
+2 & 3 % 3 2 & (3 % 3) (2 & 3) % 3
+0 0 2
+create or replace view v1 as select 2 & 3 ^ 3, 2 & (3 ^ 3), (2 & 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 ^ 3 AS `2 & 3 ^ 3`,2 & 3 ^ 3 AS `2 & (3 ^ 3)`,(2 & 3) ^ 3 AS `(2 & 3) ^ 3`
+select 2 & 3 ^ 3, 2 & (3 ^ 3), (2 & 3) ^ 3 union select * from v1;
+2 & 3 ^ 3 2 & (3 ^ 3) (2 & 3) ^ 3
+0 0 1
+create or replace view v1 as select 2 & 3 BETWEEN 1 AND 3, 2 & (3 BETWEEN 1 AND 3), (2 & 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 3 between 1 and 3 AS `2 & 3 BETWEEN 1 AND 3`,2 & (3 between 1 and 3) AS `2 & (3 BETWEEN 1 AND 3)`,2 & 3 between 1 and 3 AS `(2 & 3) BETWEEN 1 AND 3`
+select 2 & 3 BETWEEN 1 AND 3, 2 & (3 BETWEEN 1 AND 3), (2 & 3) BETWEEN 1 AND 3 union select * from v1;
+2 & 3 BETWEEN 1 AND 3 2 & (3 BETWEEN 1 AND 3) (2 & 3) BETWEEN 1 AND 3
+1 0 1
+create or replace view v1 as select 2 << 3 IS FALSE, 2 << (3 IS FALSE), (2 << 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 is false AS `2 << 3 IS FALSE`,2 << (3 is false) AS `2 << (3 IS FALSE)`,2 << 3 is false AS `(2 << 3) IS FALSE`
+select 2 << 3 IS FALSE, 2 << (3 IS FALSE), (2 << 3) IS FALSE union select * from v1;
+2 << 3 IS FALSE 2 << (3 IS FALSE) (2 << 3) IS FALSE
+0 2 0
+create or replace view v1 as select charset(2 << 3 COLLATE latin1_bin), charset(2 << (3 COLLATE latin1_bin)), charset((2 << 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 << 3 collate latin1_bin) AS `charset(2 << 3 COLLATE latin1_bin)`,charset(2 << 3 collate latin1_bin) AS `charset(2 << (3 COLLATE latin1_bin))`,charset((2 << 3) collate latin1_bin) AS `charset((2 << 3) COLLATE latin1_bin)`
+select charset(2 << 3 COLLATE latin1_bin), charset(2 << (3 COLLATE latin1_bin)), charset((2 << 3) COLLATE latin1_bin) union select * from v1;
+charset(2 << 3 COLLATE latin1_bin) charset(2 << (3 COLLATE latin1_bin)) charset((2 << 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 << 3 IN (0,1), 2 << (3 IN (0,1)), (2 << 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 in (0,1) AS `2 << 3 IN (0,1)`,2 << (3 in (0,1)) AS `2 << (3 IN (0,1))`,2 << 3 in (0,1) AS `(2 << 3) IN (0,1)`
+select 2 << 3 IN (0,1), 2 << (3 IN (0,1)), (2 << 3) IN (0,1) union select * from v1;
+2 << 3 IN (0,1) 2 << (3 IN (0,1)) (2 << 3) IN (0,1)
+0 2 0
+create or replace view v1 as select 2 << 3 OR 3, 2 << (3 OR 3), (2 << 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 or 3 AS `2 << 3 OR 3`,2 << (3 or 3) AS `2 << (3 OR 3)`,2 << 3 or 3 AS `(2 << 3) OR 3`
+select 2 << 3 OR 3, 2 << (3 OR 3), (2 << 3) OR 3 union select * from v1;
+2 << 3 OR 3 2 << (3 OR 3) (2 << 3) OR 3
+1 4 1
+create or replace view v1 as select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 or 3 AS `2 << 3 || 3`,2 << (3 or 3) AS `2 << (3 || 3)`,2 << 3 or 3 AS `(2 << 3) || 3`
+select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3 union select * from v1;
+2 << 3 || 3 2 << (3 || 3) (2 << 3) || 3
+1 4 1
+create or replace view v1 as select 2 << 3 XOR 3, 2 << (3 XOR 3), (2 << 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 xor 3 AS `2 << 3 XOR 3`,2 << (3 xor 3) AS `2 << (3 XOR 3)`,2 << 3 xor 3 AS `(2 << 3) XOR 3`
+select 2 << 3 XOR 3, 2 << (3 XOR 3), (2 << 3) XOR 3 union select * from v1;
+2 << 3 XOR 3 2 << (3 XOR 3) (2 << 3) XOR 3
+0 2 0
+create or replace view v1 as select 2 << 3 AND 3, 2 << (3 AND 3), (2 << 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 and 3 AS `2 << 3 AND 3`,2 << (3 and 3) AS `2 << (3 AND 3)`,2 << 3 and 3 AS `(2 << 3) AND 3`
+select 2 << 3 AND 3, 2 << (3 AND 3), (2 << 3) AND 3 union select * from v1;
+2 << 3 AND 3 2 << (3 AND 3) (2 << 3) AND 3
+1 4 1
+create or replace view v1 as select 2 << 3 && 3, 2 << (3 && 3), (2 << 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 and 3 AS `2 << 3 && 3`,2 << (3 and 3) AS `2 << (3 && 3)`,2 << 3 and 3 AS `(2 << 3) && 3`
+select 2 << 3 && 3, 2 << (3 && 3), (2 << 3) && 3 union select * from v1;
+2 << 3 && 3 2 << (3 && 3) (2 << 3) && 3
+1 4 1
+create or replace view v1 as select 2 << 3 = 3, 2 << (3 = 3), (2 << 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 = 3 AS `2 << 3 = 3`,2 << (3 = 3) AS `2 << (3 = 3)`,2 << 3 = 3 AS `(2 << 3) = 3`
+select 2 << 3 = 3, 2 << (3 = 3), (2 << 3) = 3 union select * from v1;
+2 << 3 = 3 2 << (3 = 3) (2 << 3) = 3
+0 4 0
+create or replace view v1 as select 2 << 3 <=> 3, 2 << (3 <=> 3), (2 << 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 <=> 3 AS `2 << 3 <=> 3`,2 << (3 <=> 3) AS `2 << (3 <=> 3)`,2 << 3 <=> 3 AS `(2 << 3) <=> 3`
+select 2 << 3 <=> 3, 2 << (3 <=> 3), (2 << 3) <=> 3 union select * from v1;
+2 << 3 <=> 3 2 << (3 <=> 3) (2 << 3) <=> 3
+0 4 0
+create or replace view v1 as select 2 << 3 >= 3, 2 << (3 >= 3), (2 << 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 >= 3 AS `2 << 3 >= 3`,2 << (3 >= 3) AS `2 << (3 >= 3)`,2 << 3 >= 3 AS `(2 << 3) >= 3`
+select 2 << 3 >= 3, 2 << (3 >= 3), (2 << 3) >= 3 union select * from v1;
+2 << 3 >= 3 2 << (3 >= 3) (2 << 3) >= 3
+1 4 1
+create or replace view v1 as select 2 << 3 <= 3, 2 << (3 <= 3), (2 << 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 <= 3 AS `2 << 3 <= 3`,2 << (3 <= 3) AS `2 << (3 <= 3)`,2 << 3 <= 3 AS `(2 << 3) <= 3`
+select 2 << 3 <= 3, 2 << (3 <= 3), (2 << 3) <= 3 union select * from v1;
+2 << 3 <= 3 2 << (3 <= 3) (2 << 3) <= 3
+0 4 0
+create or replace view v1 as select 2 << 3 < 3, 2 << (3 < 3), (2 << 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 < 3 AS `2 << 3 < 3`,2 << (3 < 3) AS `2 << (3 < 3)`,2 << 3 < 3 AS `(2 << 3) < 3`
+select 2 << 3 < 3, 2 << (3 < 3), (2 << 3) < 3 union select * from v1;
+2 << 3 < 3 2 << (3 < 3) (2 << 3) < 3
+0 2 0
+create or replace view v1 as select 2 << 3 <> 3, 2 << (3 <> 3), (2 << 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 <> 3 AS `2 << 3 <> 3`,2 << (3 <> 3) AS `2 << (3 <> 3)`,2 << 3 <> 3 AS `(2 << 3) <> 3`
+select 2 << 3 <> 3, 2 << (3 <> 3), (2 << 3) <> 3 union select * from v1;
+2 << 3 <> 3 2 << (3 <> 3) (2 << 3) <> 3
+1 2 1
+create or replace view v1 as select 2 << 3 > 3, 2 << (3 > 3), (2 << 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 > 3 AS `2 << 3 > 3`,2 << (3 > 3) AS `2 << (3 > 3)`,2 << 3 > 3 AS `(2 << 3) > 3`
+select 2 << 3 > 3, 2 << (3 > 3), (2 << 3) > 3 union select * from v1;
+2 << 3 > 3 2 << (3 > 3) (2 << 3) > 3
+1 2 1
+create or replace view v1 as select 2 << 3 != 3, 2 << (3 != 3), (2 << 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 <> 3 AS `2 << 3 != 3`,2 << (3 <> 3) AS `2 << (3 != 3)`,2 << 3 <> 3 AS `(2 << 3) != 3`
+select 2 << 3 != 3, 2 << (3 != 3), (2 << 3) != 3 union select * from v1;
+2 << 3 != 3 2 << (3 != 3) (2 << 3) != 3
+1 2 1
+create or replace view v1 as select 2 << 3 LIKE 3, 2 << (3 LIKE 3), (2 << 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 like 3 AS `2 << 3 LIKE 3`,2 << (3 like 3) AS `2 << (3 LIKE 3)`,2 << 3 like 3 AS `(2 << 3) LIKE 3`
+select 2 << 3 LIKE 3, 2 << (3 LIKE 3), (2 << 3) LIKE 3 union select * from v1;
+2 << 3 LIKE 3 2 << (3 LIKE 3) (2 << 3) LIKE 3
+0 4 0
+create or replace view v1 as select 2 << 3 REGEXP 3, 2 << (3 REGEXP 3), (2 << 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 regexp 3 AS `2 << 3 REGEXP 3`,2 << (3 regexp 3) AS `2 << (3 REGEXP 3)`,2 << 3 regexp 3 AS `(2 << 3) REGEXP 3`
+select 2 << 3 REGEXP 3, 2 << (3 REGEXP 3), (2 << 3) REGEXP 3 union select * from v1;
+2 << 3 REGEXP 3 2 << (3 REGEXP 3) (2 << 3) REGEXP 3
+0 4 0
+create or replace view v1 as select 2 << 3 | 3, 2 << (3 | 3), (2 << 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 | 3 AS `2 << 3 | 3`,2 << (3 | 3) AS `2 << (3 | 3)`,2 << 3 | 3 AS `(2 << 3) | 3`
+select 2 << 3 | 3, 2 << (3 | 3), (2 << 3) | 3 union select * from v1;
+2 << 3 | 3 2 << (3 | 3) (2 << 3) | 3
+19 16 19
+create or replace view v1 as select 2 << 3 & 3, 2 << (3 & 3), (2 << 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 & 3 AS `2 << 3 & 3`,2 << (3 & 3) AS `2 << (3 & 3)`,2 << 3 & 3 AS `(2 << 3) & 3`
+select 2 << 3 & 3, 2 << (3 & 3), (2 << 3) & 3 union select * from v1;
+2 << 3 & 3 2 << (3 & 3) (2 << 3) & 3
+0 16 0
+create or replace view v1 as select 2 << 3 << 3, 2 << (3 << 3), (2 << 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 << 3 AS `2 << 3 << 3`,2 << (3 << 3) AS `2 << (3 << 3)`,2 << 3 << 3 AS `(2 << 3) << 3`
+select 2 << 3 << 3, 2 << (3 << 3), (2 << 3) << 3 union select * from v1;
+2 << 3 << 3 2 << (3 << 3) (2 << 3) << 3
+128 33554432 128
+create or replace view v1 as select 2 << 2 >> 3, 2 << (2 >> 3), (2 << 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 2 >> 3 AS `2 << 2 >> 3`,2 << (2 >> 3) AS `2 << (2 >> 3)`,2 << 2 >> 3 AS `(2 << 2) >> 3`
+select 2 << 2 >> 3, 2 << (2 >> 3), (2 << 2) >> 3 union select * from v1;
+2 << 2 >> 3 2 << (2 >> 3) (2 << 2) >> 3
+1 2 1
+create or replace view v1 as select 2 << '2000-01-01' +INTERVAL 1 DAY, 2 << ('2000-01-01' +INTERVAL 1 DAY), (2 << '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << '2000-01-01' + interval 1 day AS `2 << '2000-01-01' +INTERVAL 1 DAY`,2 << '2000-01-01' + interval 1 day AS `2 << ('2000-01-01' +INTERVAL 1 DAY)`,(2 << '2000-01-01') + interval 1 day AS `(2 << '2000-01-01') +INTERVAL 1 DAY`
+select 2 << '2000-01-01' +INTERVAL 1 DAY, 2 << ('2000-01-01' +INTERVAL 1 DAY), (2 << '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 << '2000-01-01' +INTERVAL 1 DAY 2 << ('2000-01-01' +INTERVAL 1 DAY) (2 << '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 << 3 + 3, 2 << (3 + 3), (2 << 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 + 3 AS `2 << 3 + 3`,2 << 3 + 3 AS `2 << (3 + 3)`,(2 << 3) + 3 AS `(2 << 3) + 3`
+select 2 << 3 + 3, 2 << (3 + 3), (2 << 3) + 3 union select * from v1;
+2 << 3 + 3 2 << (3 + 3) (2 << 3) + 3
+128 128 19
+create or replace view v1 as select 2 << 3 - 3, 2 << (3 - 3), (2 << 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 - 3 AS `2 << 3 - 3`,2 << 3 - 3 AS `2 << (3 - 3)`,(2 << 3) - 3 AS `(2 << 3) - 3`
+select 2 << 3 - 3, 2 << (3 - 3), (2 << 3) - 3 union select * from v1;
+2 << 3 - 3 2 << (3 - 3) (2 << 3) - 3
+2 2 13
+create or replace view v1 as select 2 << 3 * 3, 2 << (3 * 3), (2 << 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 * 3 AS `2 << 3 * 3`,2 << 3 * 3 AS `2 << (3 * 3)`,(2 << 3) * 3 AS `(2 << 3) * 3`
+select 2 << 3 * 3, 2 << (3 * 3), (2 << 3) * 3 union select * from v1;
+2 << 3 * 3 2 << (3 * 3) (2 << 3) * 3
+1024 1024 48
+create or replace view v1 as select 2 << 3 / 3, 2 << (3 / 3), (2 << 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 / 3 AS `2 << 3 / 3`,2 << 3 / 3 AS `2 << (3 / 3)`,(2 << 3) / 3 AS `(2 << 3) / 3`
+select 2 << 3 / 3, 2 << (3 / 3), (2 << 3) / 3 union select * from v1;
+2 << 3 / 3 2 << (3 / 3) (2 << 3) / 3
+4 4 5.3333
+create or replace view v1 as select 2 << 3 DIV 3, 2 << (3 DIV 3), (2 << 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 DIV 3 AS `2 << 3 DIV 3`,2 << 3 DIV 3 AS `2 << (3 DIV 3)`,(2 << 3) DIV 3 AS `(2 << 3) DIV 3`
+select 2 << 3 DIV 3, 2 << (3 DIV 3), (2 << 3) DIV 3 union select * from v1;
+2 << 3 DIV 3 2 << (3 DIV 3) (2 << 3) DIV 3
+4 4 5
+create or replace view v1 as select 2 << 3 MOD 3, 2 << (3 MOD 3), (2 << 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 MOD 3 AS `2 << 3 MOD 3`,2 << 3 MOD 3 AS `2 << (3 MOD 3)`,(2 << 3) MOD 3 AS `(2 << 3) MOD 3`
+select 2 << 3 MOD 3, 2 << (3 MOD 3), (2 << 3) MOD 3 union select * from v1;
+2 << 3 MOD 3 2 << (3 MOD 3) (2 << 3) MOD 3
+2 2 1
+create or replace view v1 as select 2 << 3 % 3, 2 << (3 % 3), (2 << 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 MOD 3 AS `2 << 3 % 3`,2 << 3 MOD 3 AS `2 << (3 % 3)`,(2 << 3) MOD 3 AS `(2 << 3) % 3`
+select 2 << 3 % 3, 2 << (3 % 3), (2 << 3) % 3 union select * from v1;
+2 << 3 % 3 2 << (3 % 3) (2 << 3) % 3
+2 2 1
+create or replace view v1 as select 2 << 3 ^ 3, 2 << (3 ^ 3), (2 << 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 ^ 3 AS `2 << 3 ^ 3`,2 << 3 ^ 3 AS `2 << (3 ^ 3)`,(2 << 3) ^ 3 AS `(2 << 3) ^ 3`
+select 2 << 3 ^ 3, 2 << (3 ^ 3), (2 << 3) ^ 3 union select * from v1;
+2 << 3 ^ 3 2 << (3 ^ 3) (2 << 3) ^ 3
+2 2 19
+create or replace view v1 as select 2 << 3 BETWEEN 1 AND 3, 2 << (3 BETWEEN 1 AND 3), (2 << 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 between 1 and 3 AS `2 << 3 BETWEEN 1 AND 3`,2 << (3 between 1 and 3) AS `2 << (3 BETWEEN 1 AND 3)`,2 << 3 between 1 and 3 AS `(2 << 3) BETWEEN 1 AND 3`
+select 2 << 3 BETWEEN 1 AND 3, 2 << (3 BETWEEN 1 AND 3), (2 << 3) BETWEEN 1 AND 3 union select * from v1;
+2 << 3 BETWEEN 1 AND 3 2 << (3 BETWEEN 1 AND 3) (2 << 3) BETWEEN 1 AND 3
+0 4 0
+create or replace view v1 as select 2 >> 3 IS FALSE, 2 >> (3 IS FALSE), (2 >> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 is false AS `2 >> 3 IS FALSE`,2 >> (3 is false) AS `2 >> (3 IS FALSE)`,2 >> 3 is false AS `(2 >> 3) IS FALSE`
+select 2 >> 3 IS FALSE, 2 >> (3 IS FALSE), (2 >> 3) IS FALSE union select * from v1;
+2 >> 3 IS FALSE 2 >> (3 IS FALSE) (2 >> 3) IS FALSE
+1 2 1
+create or replace view v1 as select charset(2 >> 3 COLLATE latin1_bin), charset(2 >> (3 COLLATE latin1_bin)), charset((2 >> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 >> 3 collate latin1_bin) AS `charset(2 >> 3 COLLATE latin1_bin)`,charset(2 >> 3 collate latin1_bin) AS `charset(2 >> (3 COLLATE latin1_bin))`,charset((2 >> 3) collate latin1_bin) AS `charset((2 >> 3) COLLATE latin1_bin)`
+select charset(2 >> 3 COLLATE latin1_bin), charset(2 >> (3 COLLATE latin1_bin)), charset((2 >> 3) COLLATE latin1_bin) union select * from v1;
+charset(2 >> 3 COLLATE latin1_bin) charset(2 >> (3 COLLATE latin1_bin)) charset((2 >> 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 >> 3 IN (0,1), 2 >> (3 IN (0,1)), (2 >> 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 in (0,1) AS `2 >> 3 IN (0,1)`,2 >> (3 in (0,1)) AS `2 >> (3 IN (0,1))`,2 >> 3 in (0,1) AS `(2 >> 3) IN (0,1)`
+select 2 >> 3 IN (0,1), 2 >> (3 IN (0,1)), (2 >> 3) IN (0,1) union select * from v1;
+2 >> 3 IN (0,1) 2 >> (3 IN (0,1)) (2 >> 3) IN (0,1)
+1 2 1
+create or replace view v1 as select 2 >> 3 OR 0, 2 >> (3 OR 0), (2 >> 3) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 or 0 AS `2 >> 3 OR 0`,2 >> (3 or 0) AS `2 >> (3 OR 0)`,2 >> 3 or 0 AS `(2 >> 3) OR 0`
+select 2 >> 3 OR 0, 2 >> (3 OR 0), (2 >> 3) OR 0 union select * from v1;
+2 >> 3 OR 0 2 >> (3 OR 0) (2 >> 3) OR 0
+0 1 0
+create or replace view v1 as select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 or 0 AS `2 >> 3 || 0`,2 >> (3 or 0) AS `2 >> (3 || 0)`,2 >> 3 or 0 AS `(2 >> 3) || 0`
+select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0 union select * from v1;
+2 >> 3 || 0 2 >> (3 || 0) (2 >> 3) || 0
+0 1 0
+create or replace view v1 as select 2 >> 3 XOR 3, 2 >> (3 XOR 3), (2 >> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 xor 3 AS `2 >> 3 XOR 3`,2 >> (3 xor 3) AS `2 >> (3 XOR 3)`,2 >> 3 xor 3 AS `(2 >> 3) XOR 3`
+select 2 >> 3 XOR 3, 2 >> (3 XOR 3), (2 >> 3) XOR 3 union select * from v1;
+2 >> 3 XOR 3 2 >> (3 XOR 3) (2 >> 3) XOR 3
+1 2 1
+create or replace view v1 as select 2 >> 3 AND 3, 2 >> (3 AND 3), (2 >> 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 and 3 AS `2 >> 3 AND 3`,2 >> (3 and 3) AS `2 >> (3 AND 3)`,2 >> 3 and 3 AS `(2 >> 3) AND 3`
+select 2 >> 3 AND 3, 2 >> (3 AND 3), (2 >> 3) AND 3 union select * from v1;
+2 >> 3 AND 3 2 >> (3 AND 3) (2 >> 3) AND 3
+0 1 0
+create or replace view v1 as select 2 >> 3 && 3, 2 >> (3 && 3), (2 >> 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 and 3 AS `2 >> 3 && 3`,2 >> (3 and 3) AS `2 >> (3 && 3)`,2 >> 3 and 3 AS `(2 >> 3) && 3`
+select 2 >> 3 && 3, 2 >> (3 && 3), (2 >> 3) && 3 union select * from v1;
+2 >> 3 && 3 2 >> (3 && 3) (2 >> 3) && 3
+0 1 0
+create or replace view v1 as select 2 >> 3 = 3, 2 >> (3 = 3), (2 >> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 = 3 AS `2 >> 3 = 3`,2 >> (3 = 3) AS `2 >> (3 = 3)`,2 >> 3 = 3 AS `(2 >> 3) = 3`
+select 2 >> 3 = 3, 2 >> (3 = 3), (2 >> 3) = 3 union select * from v1;
+2 >> 3 = 3 2 >> (3 = 3) (2 >> 3) = 3
+0 1 0
+create or replace view v1 as select 2 >> 3 <=> 3, 2 >> (3 <=> 3), (2 >> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 <=> 3 AS `2 >> 3 <=> 3`,2 >> (3 <=> 3) AS `2 >> (3 <=> 3)`,2 >> 3 <=> 3 AS `(2 >> 3) <=> 3`
+select 2 >> 3 <=> 3, 2 >> (3 <=> 3), (2 >> 3) <=> 3 union select * from v1;
+2 >> 3 <=> 3 2 >> (3 <=> 3) (2 >> 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 >> 3 >= 3, 2 >> (3 >= 3), (2 >> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 >= 3 AS `2 >> 3 >= 3`,2 >> (3 >= 3) AS `2 >> (3 >= 3)`,2 >> 3 >= 3 AS `(2 >> 3) >= 3`
+select 2 >> 3 >= 3, 2 >> (3 >= 3), (2 >> 3) >= 3 union select * from v1;
+2 >> 3 >= 3 2 >> (3 >= 3) (2 >> 3) >= 3
+0 1 0
+create or replace view v1 as select 2 >> 3 <= 0, 2 >> (3 <= 0), (2 >> 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 <= 0 AS `2 >> 3 <= 0`,2 >> (3 <= 0) AS `2 >> (3 <= 0)`,2 >> 3 <= 0 AS `(2 >> 3) <= 0`
+select 2 >> 3 <= 0, 2 >> (3 <= 0), (2 >> 3) <= 0 union select * from v1;
+2 >> 3 <= 0 2 >> (3 <= 0) (2 >> 3) <= 0
+1 2 1
+create or replace view v1 as select 2 >> 3 < 3, 2 >> (3 < 3), (2 >> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 < 3 AS `2 >> 3 < 3`,2 >> (3 < 3) AS `2 >> (3 < 3)`,2 >> 3 < 3 AS `(2 >> 3) < 3`
+select 2 >> 3 < 3, 2 >> (3 < 3), (2 >> 3) < 3 union select * from v1;
+2 >> 3 < 3 2 >> (3 < 3) (2 >> 3) < 3
+1 2 1
+create or replace view v1 as select 2 >> 3 <> 3, 2 >> (3 <> 3), (2 >> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 <> 3 AS `2 >> 3 <> 3`,2 >> (3 <> 3) AS `2 >> (3 <> 3)`,2 >> 3 <> 3 AS `(2 >> 3) <> 3`
+select 2 >> 3 <> 3, 2 >> (3 <> 3), (2 >> 3) <> 3 union select * from v1;
+2 >> 3 <> 3 2 >> (3 <> 3) (2 >> 3) <> 3
+1 2 1
+create or replace view v1 as select 2 >> 3 > 3, 2 >> (3 > 3), (2 >> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 > 3 AS `2 >> 3 > 3`,2 >> (3 > 3) AS `2 >> (3 > 3)`,2 >> 3 > 3 AS `(2 >> 3) > 3`
+select 2 >> 3 > 3, 2 >> (3 > 3), (2 >> 3) > 3 union select * from v1;
+2 >> 3 > 3 2 >> (3 > 3) (2 >> 3) > 3
+0 2 0
+create or replace view v1 as select 2 >> 3 != 3, 2 >> (3 != 3), (2 >> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 <> 3 AS `2 >> 3 != 3`,2 >> (3 <> 3) AS `2 >> (3 != 3)`,2 >> 3 <> 3 AS `(2 >> 3) != 3`
+select 2 >> 3 != 3, 2 >> (3 != 3), (2 >> 3) != 3 union select * from v1;
+2 >> 3 != 3 2 >> (3 != 3) (2 >> 3) != 3
+1 2 1
+create or replace view v1 as select 2 >> 3 LIKE 3, 2 >> (3 LIKE 3), (2 >> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 like 3 AS `2 >> 3 LIKE 3`,2 >> (3 like 3) AS `2 >> (3 LIKE 3)`,2 >> 3 like 3 AS `(2 >> 3) LIKE 3`
+select 2 >> 3 LIKE 3, 2 >> (3 LIKE 3), (2 >> 3) LIKE 3 union select * from v1;
+2 >> 3 LIKE 3 2 >> (3 LIKE 3) (2 >> 3) LIKE 3
+0 1 0
+create or replace view v1 as select 2 >> 3 REGEXP 3, 2 >> (3 REGEXP 3), (2 >> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 regexp 3 AS `2 >> 3 REGEXP 3`,2 >> (3 regexp 3) AS `2 >> (3 REGEXP 3)`,2 >> 3 regexp 3 AS `(2 >> 3) REGEXP 3`
+select 2 >> 3 REGEXP 3, 2 >> (3 REGEXP 3), (2 >> 3) REGEXP 3 union select * from v1;
+2 >> 3 REGEXP 3 2 >> (3 REGEXP 3) (2 >> 3) REGEXP 3
+0 1 0
+create or replace view v1 as select 2 >> 3 | 3, 2 >> (3 | 3), (2 >> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 | 3 AS `2 >> 3 | 3`,2 >> (3 | 3) AS `2 >> (3 | 3)`,2 >> 3 | 3 AS `(2 >> 3) | 3`
+select 2 >> 3 | 3, 2 >> (3 | 3), (2 >> 3) | 3 union select * from v1;
+2 >> 3 | 3 2 >> (3 | 3) (2 >> 3) | 3
+3 0 3
+create or replace view v1 as select 2 >> 3 & 1, 2 >> (3 & 1), (2 >> 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 & 1 AS `2 >> 3 & 1`,2 >> (3 & 1) AS `2 >> (3 & 1)`,2 >> 3 & 1 AS `(2 >> 3) & 1`
+select 2 >> 3 & 1, 2 >> (3 & 1), (2 >> 3) & 1 union select * from v1;
+2 >> 3 & 1 2 >> (3 & 1) (2 >> 3) & 1
+0 1 0
+create or replace view v1 as select 2 >> 1 << 3, 2 >> (1 << 3), (2 >> 1) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 1 << 3 AS `2 >> 1 << 3`,2 >> (1 << 3) AS `2 >> (1 << 3)`,2 >> 1 << 3 AS `(2 >> 1) << 3`
+select 2 >> 1 << 3, 2 >> (1 << 3), (2 >> 1) << 3 union select * from v1;
+2 >> 1 << 3 2 >> (1 << 3) (2 >> 1) << 3
+8 0 8
+create or replace view v1 as select 2 >> 3 >> 3, 2 >> (3 >> 3), (2 >> 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 >> 3 AS `2 >> 3 >> 3`,2 >> (3 >> 3) AS `2 >> (3 >> 3)`,2 >> 3 >> 3 AS `(2 >> 3) >> 3`
+select 2 >> 3 >> 3, 2 >> (3 >> 3), (2 >> 3) >> 3 union select * from v1;
+2 >> 3 >> 3 2 >> (3 >> 3) (2 >> 3) >> 3
+0 2 0
+create or replace view v1 as select 2 >> '2000-01-01' +INTERVAL 1 DAY, 2 >> ('2000-01-01' +INTERVAL 1 DAY), (2 >> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> '2000-01-01' + interval 1 day AS `2 >> '2000-01-01' +INTERVAL 1 DAY`,2 >> '2000-01-01' + interval 1 day AS `2 >> ('2000-01-01' +INTERVAL 1 DAY)`,(2 >> '2000-01-01') + interval 1 day AS `(2 >> '2000-01-01') +INTERVAL 1 DAY`
+select 2 >> '2000-01-01' +INTERVAL 1 DAY, 2 >> ('2000-01-01' +INTERVAL 1 DAY), (2 >> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 >> '2000-01-01' +INTERVAL 1 DAY 2 >> ('2000-01-01' +INTERVAL 1 DAY) (2 >> '2000-01-01') +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 >> 3 + 3, 2 >> (3 + 3), (2 >> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 + 3 AS `2 >> 3 + 3`,2 >> 3 + 3 AS `2 >> (3 + 3)`,(2 >> 3) + 3 AS `(2 >> 3) + 3`
+select 2 >> 3 + 3, 2 >> (3 + 3), (2 >> 3) + 3 union select * from v1;
+2 >> 3 + 3 2 >> (3 + 3) (2 >> 3) + 3
+0 0 3
+create or replace view v1 as select 2 >> 1 - 1, 2 >> (1 - 1), (2 >> 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 1 - 1 AS `2 >> 1 - 1`,2 >> 1 - 1 AS `2 >> (1 - 1)`,(2 >> 1) - 1 AS `(2 >> 1) - 1`
+select 2 >> 1 - 1, 2 >> (1 - 1), (2 >> 1) - 1 union select * from v1;
+2 >> 1 - 1 2 >> (1 - 1) (2 >> 1) - 1
+2 2 0
+create or replace view v1 as select 2 >> 1 * 3, 2 >> (1 * 3), (2 >> 1) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 1 * 3 AS `2 >> 1 * 3`,2 >> 1 * 3 AS `2 >> (1 * 3)`,(2 >> 1) * 3 AS `(2 >> 1) * 3`
+select 2 >> 1 * 3, 2 >> (1 * 3), (2 >> 1) * 3 union select * from v1;
+2 >> 1 * 3 2 >> (1 * 3) (2 >> 1) * 3
+0 0 3
+create or replace view v1 as select 2 >> 3 / 3, 2 >> (3 / 3), (2 >> 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 / 3 AS `2 >> 3 / 3`,2 >> 3 / 3 AS `2 >> (3 / 3)`,(2 >> 3) / 3 AS `(2 >> 3) / 3`
+select 2 >> 3 / 3, 2 >> (3 / 3), (2 >> 3) / 3 union select * from v1;
+2 >> 3 / 3 2 >> (3 / 3) (2 >> 3) / 3
+1 1 0.0000
+create or replace view v1 as select 2 >> 3 DIV 3, 2 >> (3 DIV 3), (2 >> 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 DIV 3 AS `2 >> 3 DIV 3`,2 >> 3 DIV 3 AS `2 >> (3 DIV 3)`,(2 >> 3) DIV 3 AS `(2 >> 3) DIV 3`
+select 2 >> 3 DIV 3, 2 >> (3 DIV 3), (2 >> 3) DIV 3 union select * from v1;
+2 >> 3 DIV 3 2 >> (3 DIV 3) (2 >> 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 >> 3 MOD 3, 2 >> (3 MOD 3), (2 >> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 MOD 3 AS `2 >> 3 MOD 3`,2 >> 3 MOD 3 AS `2 >> (3 MOD 3)`,(2 >> 3) MOD 3 AS `(2 >> 3) MOD 3`
+select 2 >> 3 MOD 3, 2 >> (3 MOD 3), (2 >> 3) MOD 3 union select * from v1;
+2 >> 3 MOD 3 2 >> (3 MOD 3) (2 >> 3) MOD 3
+2 2 0
+create or replace view v1 as select 2 >> 3 % 3, 2 >> (3 % 3), (2 >> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 MOD 3 AS `2 >> 3 % 3`,2 >> 3 MOD 3 AS `2 >> (3 % 3)`,(2 >> 3) MOD 3 AS `(2 >> 3) % 3`
+select 2 >> 3 % 3, 2 >> (3 % 3), (2 >> 3) % 3 union select * from v1;
+2 >> 3 % 3 2 >> (3 % 3) (2 >> 3) % 3
+2 2 0
+create or replace view v1 as select 2 >> 3 ^ 3, 2 >> (3 ^ 3), (2 >> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 ^ 3 AS `2 >> 3 ^ 3`,2 >> 3 ^ 3 AS `2 >> (3 ^ 3)`,(2 >> 3) ^ 3 AS `(2 >> 3) ^ 3`
+select 2 >> 3 ^ 3, 2 >> (3 ^ 3), (2 >> 3) ^ 3 union select * from v1;
+2 >> 3 ^ 3 2 >> (3 ^ 3) (2 >> 3) ^ 3
+2 2 3
+create or replace view v1 as select 2 >> 3 BETWEEN 1 AND 3, 2 >> (3 BETWEEN 1 AND 3), (2 >> 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 between 1 and 3 AS `2 >> 3 BETWEEN 1 AND 3`,2 >> (3 between 1 and 3) AS `2 >> (3 BETWEEN 1 AND 3)`,2 >> 3 between 1 and 3 AS `(2 >> 3) BETWEEN 1 AND 3`
+select 2 >> 3 BETWEEN 1 AND 3, 2 >> (3 BETWEEN 1 AND 3), (2 >> 3) BETWEEN 1 AND 3 union select * from v1;
+2 >> 3 BETWEEN 1 AND 3 2 >> (3 BETWEEN 1 AND 3) (2 >> 3) BETWEEN 1 AND 3
+0 1 0
+create or replace view v1 as select 2 + 3 IS FALSE, 2 + (3 IS FALSE), (2 + 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 is false AS `2 + 3 IS FALSE`,2 + (3 is false) AS `2 + (3 IS FALSE)`,2 + 3 is false AS `(2 + 3) IS FALSE`
+select 2 + 3 IS FALSE, 2 + (3 IS FALSE), (2 + 3) IS FALSE union select * from v1;
+2 + 3 IS FALSE 2 + (3 IS FALSE) (2 + 3) IS FALSE
+0 2 0
+create or replace view v1 as select charset(2 + 3 COLLATE latin1_bin), charset(2 + (3 COLLATE latin1_bin)), charset((2 + 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 + 3 collate latin1_bin) AS `charset(2 + 3 COLLATE latin1_bin)`,charset(2 + 3 collate latin1_bin) AS `charset(2 + (3 COLLATE latin1_bin))`,charset((2 + 3) collate latin1_bin) AS `charset((2 + 3) COLLATE latin1_bin)`
+select charset(2 + 3 COLLATE latin1_bin), charset(2 + (3 COLLATE latin1_bin)), charset((2 + 3) COLLATE latin1_bin) union select * from v1;
+charset(2 + 3 COLLATE latin1_bin) charset(2 + (3 COLLATE latin1_bin)) charset((2 + 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 + 3 IN (0,1), 2 + (3 IN (0,1)), (2 + 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 in (0,1) AS `2 + 3 IN (0,1)`,2 + (3 in (0,1)) AS `2 + (3 IN (0,1))`,2 + 3 in (0,1) AS `(2 + 3) IN (0,1)`
+select 2 + 3 IN (0,1), 2 + (3 IN (0,1)), (2 + 3) IN (0,1) union select * from v1;
+2 + 3 IN (0,1) 2 + (3 IN (0,1)) (2 + 3) IN (0,1)
+0 2 0
+create or replace view v1 as select 2 + 3 OR 3, 2 + (3 OR 3), (2 + 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 or 3 AS `2 + 3 OR 3`,2 + (3 or 3) AS `2 + (3 OR 3)`,2 + 3 or 3 AS `(2 + 3) OR 3`
+select 2 + 3 OR 3, 2 + (3 OR 3), (2 + 3) OR 3 union select * from v1;
+2 + 3 OR 3 2 + (3 OR 3) (2 + 3) OR 3
+1 3 1
+create or replace view v1 as select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 or 3 AS `2 + 3 || 3`,2 + (3 or 3) AS `2 + (3 || 3)`,2 + 3 or 3 AS `(2 + 3) || 3`
+select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3 union select * from v1;
+2 + 3 || 3 2 + (3 || 3) (2 + 3) || 3
+1 3 1
+create or replace view v1 as select 2 + 3 XOR 3, 2 + (3 XOR 3), (2 + 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 xor 3 AS `2 + 3 XOR 3`,2 + (3 xor 3) AS `2 + (3 XOR 3)`,2 + 3 xor 3 AS `(2 + 3) XOR 3`
+select 2 + 3 XOR 3, 2 + (3 XOR 3), (2 + 3) XOR 3 union select * from v1;
+2 + 3 XOR 3 2 + (3 XOR 3) (2 + 3) XOR 3
+0 2 0
+create or replace view v1 as select 2 + 3 AND 3, 2 + (3 AND 3), (2 + 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 and 3 AS `2 + 3 AND 3`,2 + (3 and 3) AS `2 + (3 AND 3)`,2 + 3 and 3 AS `(2 + 3) AND 3`
+select 2 + 3 AND 3, 2 + (3 AND 3), (2 + 3) AND 3 union select * from v1;
+2 + 3 AND 3 2 + (3 AND 3) (2 + 3) AND 3
+1 3 1
+create or replace view v1 as select 2 + 3 && 3, 2 + (3 && 3), (2 + 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 and 3 AS `2 + 3 && 3`,2 + (3 and 3) AS `2 + (3 && 3)`,2 + 3 and 3 AS `(2 + 3) && 3`
+select 2 + 3 && 3, 2 + (3 && 3), (2 + 3) && 3 union select * from v1;
+2 + 3 && 3 2 + (3 && 3) (2 + 3) && 3
+1 3 1
+create or replace view v1 as select 2 + 3 = 3, 2 + (3 = 3), (2 + 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 = 3 AS `2 + 3 = 3`,2 + (3 = 3) AS `2 + (3 = 3)`,2 + 3 = 3 AS `(2 + 3) = 3`
+select 2 + 3 = 3, 2 + (3 = 3), (2 + 3) = 3 union select * from v1;
+2 + 3 = 3 2 + (3 = 3) (2 + 3) = 3
+0 3 0
+create or replace view v1 as select 2 + 3 <=> 3, 2 + (3 <=> 3), (2 + 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 <=> 3 AS `2 + 3 <=> 3`,2 + (3 <=> 3) AS `2 + (3 <=> 3)`,2 + 3 <=> 3 AS `(2 + 3) <=> 3`
+select 2 + 3 <=> 3, 2 + (3 <=> 3), (2 + 3) <=> 3 union select * from v1;
+2 + 3 <=> 3 2 + (3 <=> 3) (2 + 3) <=> 3
+0 3 0
+create or replace view v1 as select 2 + 3 >= 3, 2 + (3 >= 3), (2 + 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 >= 3 AS `2 + 3 >= 3`,2 + (3 >= 3) AS `2 + (3 >= 3)`,2 + 3 >= 3 AS `(2 + 3) >= 3`
+select 2 + 3 >= 3, 2 + (3 >= 3), (2 + 3) >= 3 union select * from v1;
+2 + 3 >= 3 2 + (3 >= 3) (2 + 3) >= 3
+1 3 1
+create or replace view v1 as select 2 + 3 <= 3, 2 + (3 <= 3), (2 + 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 <= 3 AS `2 + 3 <= 3`,2 + (3 <= 3) AS `2 + (3 <= 3)`,2 + 3 <= 3 AS `(2 + 3) <= 3`
+select 2 + 3 <= 3, 2 + (3 <= 3), (2 + 3) <= 3 union select * from v1;
+2 + 3 <= 3 2 + (3 <= 3) (2 + 3) <= 3
+0 3 0
+create or replace view v1 as select 2 + 3 < 3, 2 + (3 < 3), (2 + 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 < 3 AS `2 + 3 < 3`,2 + (3 < 3) AS `2 + (3 < 3)`,2 + 3 < 3 AS `(2 + 3) < 3`
+select 2 + 3 < 3, 2 + (3 < 3), (2 + 3) < 3 union select * from v1;
+2 + 3 < 3 2 + (3 < 3) (2 + 3) < 3
+0 2 0
+create or replace view v1 as select 2 + 3 <> 3, 2 + (3 <> 3), (2 + 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 <> 3 AS `2 + 3 <> 3`,2 + (3 <> 3) AS `2 + (3 <> 3)`,2 + 3 <> 3 AS `(2 + 3) <> 3`
+select 2 + 3 <> 3, 2 + (3 <> 3), (2 + 3) <> 3 union select * from v1;
+2 + 3 <> 3 2 + (3 <> 3) (2 + 3) <> 3
+1 2 1
+create or replace view v1 as select 2 + 3 > 3, 2 + (3 > 3), (2 + 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 > 3 AS `2 + 3 > 3`,2 + (3 > 3) AS `2 + (3 > 3)`,2 + 3 > 3 AS `(2 + 3) > 3`
+select 2 + 3 > 3, 2 + (3 > 3), (2 + 3) > 3 union select * from v1;
+2 + 3 > 3 2 + (3 > 3) (2 + 3) > 3
+1 2 1
+create or replace view v1 as select 2 + 3 != 3, 2 + (3 != 3), (2 + 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 <> 3 AS `2 + 3 != 3`,2 + (3 <> 3) AS `2 + (3 != 3)`,2 + 3 <> 3 AS `(2 + 3) != 3`
+select 2 + 3 != 3, 2 + (3 != 3), (2 + 3) != 3 union select * from v1;
+2 + 3 != 3 2 + (3 != 3) (2 + 3) != 3
+1 2 1
+create or replace view v1 as select 2 + 3 LIKE 3, 2 + (3 LIKE 3), (2 + 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 like 3 AS `2 + 3 LIKE 3`,2 + (3 like 3) AS `2 + (3 LIKE 3)`,2 + 3 like 3 AS `(2 + 3) LIKE 3`
+select 2 + 3 LIKE 3, 2 + (3 LIKE 3), (2 + 3) LIKE 3 union select * from v1;
+2 + 3 LIKE 3 2 + (3 LIKE 3) (2 + 3) LIKE 3
+0 3 0
+create or replace view v1 as select 2 + 3 REGEXP 3, 2 + (3 REGEXP 3), (2 + 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 regexp 3 AS `2 + 3 REGEXP 3`,2 + (3 regexp 3) AS `2 + (3 REGEXP 3)`,2 + 3 regexp 3 AS `(2 + 3) REGEXP 3`
+select 2 + 3 REGEXP 3, 2 + (3 REGEXP 3), (2 + 3) REGEXP 3 union select * from v1;
+2 + 3 REGEXP 3 2 + (3 REGEXP 3) (2 + 3) REGEXP 3
+0 3 0
+create or replace view v1 as select 2 + 3 | 3, 2 + (3 | 3), (2 + 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 | 3 AS `2 + 3 | 3`,2 + (3 | 3) AS `2 + (3 | 3)`,2 + 3 | 3 AS `(2 + 3) | 3`
+select 2 + 3 | 3, 2 + (3 | 3), (2 + 3) | 3 union select * from v1;
+2 + 3 | 3 2 + (3 | 3) (2 + 3) | 3
+7 5 7
+create or replace view v1 as select 2 + 3 & 3, 2 + (3 & 3), (2 + 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 & 3 AS `2 + 3 & 3`,2 + (3 & 3) AS `2 + (3 & 3)`,2 + 3 & 3 AS `(2 + 3) & 3`
+select 2 + 3 & 3, 2 + (3 & 3), (2 + 3) & 3 union select * from v1;
+2 + 3 & 3 2 + (3 & 3) (2 + 3) & 3
+1 5 1
+create or replace view v1 as select 2 + 3 << 3, 2 + (3 << 3), (2 + 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 << 3 AS `2 + 3 << 3`,2 + (3 << 3) AS `2 + (3 << 3)`,2 + 3 << 3 AS `(2 + 3) << 3`
+select 2 + 3 << 3, 2 + (3 << 3), (2 + 3) << 3 union select * from v1;
+2 + 3 << 3 2 + (3 << 3) (2 + 3) << 3
+40 26 40
+create or replace view v1 as select 2 + 3 >> 3, 2 + (3 >> 3), (2 + 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 >> 3 AS `2 + 3 >> 3`,2 + (3 >> 3) AS `2 + (3 >> 3)`,2 + 3 >> 3 AS `(2 + 3) >> 3`
+select 2 + 3 >> 3, 2 + (3 >> 3), (2 + 3) >> 3 union select * from v1;
+2 + 3 >> 3 2 + (3 >> 3) (2 + 3) >> 3
+0 2 0
+create or replace view v1 as select 2 + '2000-01-01' +INTERVAL 1 DAY, 2 + ('2000-01-01' +INTERVAL 1 DAY), (2 + '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + '2000-01-01' + interval 1 day AS `2 + '2000-01-01' +INTERVAL 1 DAY`,2 + ('2000-01-01' + interval 1 day) AS `2 + ('2000-01-01' +INTERVAL 1 DAY)`,2 + '2000-01-01' + interval 1 day AS `(2 + '2000-01-01') +INTERVAL 1 DAY`
+select 2 + '2000-01-01' +INTERVAL 1 DAY, 2 + ('2000-01-01' +INTERVAL 1 DAY), (2 + '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 + '2000-01-01' +INTERVAL 1 DAY 2 + ('2000-01-01' +INTERVAL 1 DAY) (2 + '2000-01-01') +INTERVAL 1 DAY
+NULL 20000104 NULL
+create or replace view v1 as select 2 + 3 * 3, 2 + (3 * 3), (2 + 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 * 3 AS `2 + 3 * 3`,2 + 3 * 3 AS `2 + (3 * 3)`,(2 + 3) * 3 AS `(2 + 3) * 3`
+select 2 + 3 * 3, 2 + (3 * 3), (2 + 3) * 3 union select * from v1;
+2 + 3 * 3 2 + (3 * 3) (2 + 3) * 3
+11 11 15
+create or replace view v1 as select 2 + 3 / 3, 2 + (3 / 3), (2 + 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 / 3 AS `2 + 3 / 3`,2 + 3 / 3 AS `2 + (3 / 3)`,(2 + 3) / 3 AS `(2 + 3) / 3`
+select 2 + 3 / 3, 2 + (3 / 3), (2 + 3) / 3 union select * from v1;
+2 + 3 / 3 2 + (3 / 3) (2 + 3) / 3
+3.0000 3.0000 1.6667
+create or replace view v1 as select 2 + 3 DIV 3, 2 + (3 DIV 3), (2 + 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 DIV 3 AS `2 + 3 DIV 3`,2 + 3 DIV 3 AS `2 + (3 DIV 3)`,(2 + 3) DIV 3 AS `(2 + 3) DIV 3`
+select 2 + 3 DIV 3, 2 + (3 DIV 3), (2 + 3) DIV 3 union select * from v1;
+2 + 3 DIV 3 2 + (3 DIV 3) (2 + 3) DIV 3
+3 3 1
+create or replace view v1 as select 2 + 1 MOD 3, 2 + (1 MOD 3), (2 + 1) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 1 MOD 3 AS `2 + 1 MOD 3`,2 + 1 MOD 3 AS `2 + (1 MOD 3)`,(2 + 1) MOD 3 AS `(2 + 1) MOD 3`
+select 2 + 1 MOD 3, 2 + (1 MOD 3), (2 + 1) MOD 3 union select * from v1;
+2 + 1 MOD 3 2 + (1 MOD 3) (2 + 1) MOD 3
+3 3 0
+create or replace view v1 as select 2 + 1 % 3, 2 + (1 % 3), (2 + 1) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 1 MOD 3 AS `2 + 1 % 3`,2 + 1 MOD 3 AS `2 + (1 % 3)`,(2 + 1) MOD 3 AS `(2 + 1) % 3`
+select 2 + 1 % 3, 2 + (1 % 3), (2 + 1) % 3 union select * from v1;
+2 + 1 % 3 2 + (1 % 3) (2 + 1) % 3
+3 3 0
+create or replace view v1 as select 2 + 3 ^ 3, 2 + (3 ^ 3), (2 + 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 ^ 3 AS `2 + 3 ^ 3`,2 + 3 ^ 3 AS `2 + (3 ^ 3)`,(2 + 3) ^ 3 AS `(2 + 3) ^ 3`
+select 2 + 3 ^ 3, 2 + (3 ^ 3), (2 + 3) ^ 3 union select * from v1;
+2 + 3 ^ 3 2 + (3 ^ 3) (2 + 3) ^ 3
+2 2 6
+create or replace view v1 as select 2 + 3 BETWEEN 1 AND 3, 2 + (3 BETWEEN 1 AND 3), (2 + 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 between 1 and 3 AS `2 + 3 BETWEEN 1 AND 3`,2 + (3 between 1 and 3) AS `2 + (3 BETWEEN 1 AND 3)`,2 + 3 between 1 and 3 AS `(2 + 3) BETWEEN 1 AND 3`
+select 2 + 3 BETWEEN 1 AND 3, 2 + (3 BETWEEN 1 AND 3), (2 + 3) BETWEEN 1 AND 3 union select * from v1;
+2 + 3 BETWEEN 1 AND 3 2 + (3 BETWEEN 1 AND 3) (2 + 3) BETWEEN 1 AND 3
+0 3 0
+create or replace view v1 as select 2 - 3 IS FALSE, 2 - (3 IS FALSE), (2 - 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 is false AS `2 - 3 IS FALSE`,2 - (3 is false) AS `2 - (3 IS FALSE)`,2 - 3 is false AS `(2 - 3) IS FALSE`
+select 2 - 3 IS FALSE, 2 - (3 IS FALSE), (2 - 3) IS FALSE union select * from v1;
+2 - 3 IS FALSE 2 - (3 IS FALSE) (2 - 3) IS FALSE
+0 2 0
+create or replace view v1 as select charset(2 - 3 COLLATE latin1_bin), charset(2 - (3 COLLATE latin1_bin)), charset((2 - 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 - 3 collate latin1_bin) AS `charset(2 - 3 COLLATE latin1_bin)`,charset(2 - 3 collate latin1_bin) AS `charset(2 - (3 COLLATE latin1_bin))`,charset((2 - 3) collate latin1_bin) AS `charset((2 - 3) COLLATE latin1_bin)`
+select charset(2 - 3 COLLATE latin1_bin), charset(2 - (3 COLLATE latin1_bin)), charset((2 - 3) COLLATE latin1_bin) union select * from v1;
+charset(2 - 3 COLLATE latin1_bin) charset(2 - (3 COLLATE latin1_bin)) charset((2 - 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 - 3 IN (0,1), 2 - (3 IN (0,1)), (2 - 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 in (0,1) AS `2 - 3 IN (0,1)`,2 - (3 in (0,1)) AS `2 - (3 IN (0,1))`,2 - 3 in (0,1) AS `(2 - 3) IN (0,1)`
+select 2 - 3 IN (0,1), 2 - (3 IN (0,1)), (2 - 3) IN (0,1) union select * from v1;
+2 - 3 IN (0,1) 2 - (3 IN (0,1)) (2 - 3) IN (0,1)
+0 2 0
+create or replace view v1 as select 2 - 2 OR 0, 2 - (2 OR 0), (2 - 2) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 2 or 0 AS `2 - 2 OR 0`,2 - (2 or 0) AS `2 - (2 OR 0)`,2 - 2 or 0 AS `(2 - 2) OR 0`
+select 2 - 2 OR 0, 2 - (2 OR 0), (2 - 2) OR 0 union select * from v1;
+2 - 2 OR 0 2 - (2 OR 0) (2 - 2) OR 0
+0 1 0
+create or replace view v1 as select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 2 or 0 AS `2 - 2 || 0`,2 - (2 or 0) AS `2 - (2 || 0)`,2 - 2 or 0 AS `(2 - 2) || 0`
+select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0 union select * from v1;
+2 - 2 || 0 2 - (2 || 0) (2 - 2) || 0
+0 1 0
+create or replace view v1 as select 2 - 3 XOR 3, 2 - (3 XOR 3), (2 - 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 xor 3 AS `2 - 3 XOR 3`,2 - (3 xor 3) AS `2 - (3 XOR 3)`,2 - 3 xor 3 AS `(2 - 3) XOR 3`
+select 2 - 3 XOR 3, 2 - (3 XOR 3), (2 - 3) XOR 3 union select * from v1;
+2 - 3 XOR 3 2 - (3 XOR 3) (2 - 3) XOR 3
+0 2 0
+create or replace view v1 as select 2 - 2 AND 2, 2 - (2 AND 2), (2 - 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 2 and 2 AS `2 - 2 AND 2`,2 - (2 and 2) AS `2 - (2 AND 2)`,2 - 2 and 2 AS `(2 - 2) AND 2`
+select 2 - 2 AND 2, 2 - (2 AND 2), (2 - 2) AND 2 union select * from v1;
+2 - 2 AND 2 2 - (2 AND 2) (2 - 2) AND 2
+0 1 0
+create or replace view v1 as select 2 - 2 && 2, 2 - (2 && 2), (2 - 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 2 and 2 AS `2 - 2 && 2`,2 - (2 and 2) AS `2 - (2 && 2)`,2 - 2 and 2 AS `(2 - 2) && 2`
+select 2 - 2 && 2, 2 - (2 && 2), (2 - 2) && 2 union select * from v1;
+2 - 2 && 2 2 - (2 && 2) (2 - 2) && 2
+0 1 0
+create or replace view v1 as select 2 - 3 = 3, 2 - (3 = 3), (2 - 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 = 3 AS `2 - 3 = 3`,2 - (3 = 3) AS `2 - (3 = 3)`,2 - 3 = 3 AS `(2 - 3) = 3`
+select 2 - 3 = 3, 2 - (3 = 3), (2 - 3) = 3 union select * from v1;
+2 - 3 = 3 2 - (3 = 3) (2 - 3) = 3
+0 1 0
+create or replace view v1 as select 2 - 3 <=> 3, 2 - (3 <=> 3), (2 - 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 <=> 3 AS `2 - 3 <=> 3`,2 - (3 <=> 3) AS `2 - (3 <=> 3)`,2 - 3 <=> 3 AS `(2 - 3) <=> 3`
+select 2 - 3 <=> 3, 2 - (3 <=> 3), (2 - 3) <=> 3 union select * from v1;
+2 - 3 <=> 3 2 - (3 <=> 3) (2 - 3) <=> 3
+0 1 0
+create or replace view v1 as select 2 - 3 >= 3, 2 - (3 >= 3), (2 - 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 >= 3 AS `2 - 3 >= 3`,2 - (3 >= 3) AS `2 - (3 >= 3)`,2 - 3 >= 3 AS `(2 - 3) >= 3`
+select 2 - 3 >= 3, 2 - (3 >= 3), (2 - 3) >= 3 union select * from v1;
+2 - 3 >= 3 2 - (3 >= 3) (2 - 3) >= 3
+0 1 0
+create or replace view v1 as select 2 - 3 <= 2, 2 - (3 <= 2), (2 - 3) <= 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 <= 2 AS `2 - 3 <= 2`,2 - (3 <= 2) AS `2 - (3 <= 2)`,2 - 3 <= 2 AS `(2 - 3) <= 2`
+select 2 - 3 <= 2, 2 - (3 <= 2), (2 - 3) <= 2 union select * from v1;
+2 - 3 <= 2 2 - (3 <= 2) (2 - 3) <= 2
+1 2 1
+create or replace view v1 as select 2 - 3 < 3, 2 - (3 < 3), (2 - 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 < 3 AS `2 - 3 < 3`,2 - (3 < 3) AS `2 - (3 < 3)`,2 - 3 < 3 AS `(2 - 3) < 3`
+select 2 - 3 < 3, 2 - (3 < 3), (2 - 3) < 3 union select * from v1;
+2 - 3 < 3 2 - (3 < 3) (2 - 3) < 3
+1 2 1
+create or replace view v1 as select 2 - 3 <> 3, 2 - (3 <> 3), (2 - 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 <> 3 AS `2 - 3 <> 3`,2 - (3 <> 3) AS `2 - (3 <> 3)`,2 - 3 <> 3 AS `(2 - 3) <> 3`
+select 2 - 3 <> 3, 2 - (3 <> 3), (2 - 3) <> 3 union select * from v1;
+2 - 3 <> 3 2 - (3 <> 3) (2 - 3) <> 3
+1 2 1
+create or replace view v1 as select 2 - 3 > 3, 2 - (3 > 3), (2 - 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 > 3 AS `2 - 3 > 3`,2 - (3 > 3) AS `2 - (3 > 3)`,2 - 3 > 3 AS `(2 - 3) > 3`
+select 2 - 3 > 3, 2 - (3 > 3), (2 - 3) > 3 union select * from v1;
+2 - 3 > 3 2 - (3 > 3) (2 - 3) > 3
+0 2 0
+create or replace view v1 as select 2 - 3 != 3, 2 - (3 != 3), (2 - 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 <> 3 AS `2 - 3 != 3`,2 - (3 <> 3) AS `2 - (3 != 3)`,2 - 3 <> 3 AS `(2 - 3) != 3`
+select 2 - 3 != 3, 2 - (3 != 3), (2 - 3) != 3 union select * from v1;
+2 - 3 != 3 2 - (3 != 3) (2 - 3) != 3
+1 2 1
+create or replace view v1 as select 2 - 3 LIKE 3, 2 - (3 LIKE 3), (2 - 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 like 3 AS `2 - 3 LIKE 3`,2 - (3 like 3) AS `2 - (3 LIKE 3)`,2 - 3 like 3 AS `(2 - 3) LIKE 3`
+select 2 - 3 LIKE 3, 2 - (3 LIKE 3), (2 - 3) LIKE 3 union select * from v1;
+2 - 3 LIKE 3 2 - (3 LIKE 3) (2 - 3) LIKE 3
+0 1 0
+create or replace view v1 as select 2 - 3 REGEXP 3, 2 - (3 REGEXP 3), (2 - 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 regexp 3 AS `2 - 3 REGEXP 3`,2 - (3 regexp 3) AS `2 - (3 REGEXP 3)`,2 - 3 regexp 3 AS `(2 - 3) REGEXP 3`
+select 2 - 3 REGEXP 3, 2 - (3 REGEXP 3), (2 - 3) REGEXP 3 union select * from v1;
+2 - 3 REGEXP 3 2 - (3 REGEXP 3) (2 - 3) REGEXP 3
+0 1 0
+create or replace view v1 as select 2 - 0 | 1, 2 - (0 | 1), (2 - 0) | 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 0 | 1 AS `2 - 0 | 1`,2 - (0 | 1) AS `2 - (0 | 1)`,2 - 0 | 1 AS `(2 - 0) | 1`
+select 2 - 0 | 1, 2 - (0 | 1), (2 - 0) | 1 union select * from v1;
+2 - 0 | 1 2 - (0 | 1) (2 - 0) | 1
+3 1 3
+create or replace view v1 as select 2 - 1 & 2, 2 - (1 & 2), (2 - 1) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 1 & 2 AS `2 - 1 & 2`,2 - (1 & 2) AS `2 - (1 & 2)`,2 - 1 & 2 AS `(2 - 1) & 2`
+select 2 - 1 & 2, 2 - (1 & 2), (2 - 1) & 2 union select * from v1;
+2 - 1 & 2 2 - (1 & 2) (2 - 1) & 2
+0 2 0
+create or replace view v1 as select 2 - 1 << 1, 2 - (1 << 1), (2 - 1) << 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 1 << 1 AS `2 - 1 << 1`,2 - (1 << 1) AS `2 - (1 << 1)`,2 - 1 << 1 AS `(2 - 1) << 1`
+select 2 - 1 << 1, 2 - (1 << 1), (2 - 1) << 1 union select * from v1;
+2 - 1 << 1 2 - (1 << 1) (2 - 1) << 1
+2 0 2
+create or replace view v1 as select 2 - 3 >> 3, 2 - (3 >> 3), (2 - 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 >> 3 AS `2 - 3 >> 3`,2 - (3 >> 3) AS `2 - (3 >> 3)`,2 - 3 >> 3 AS `(2 - 3) >> 3`
+select 2 - 3 >> 3, 2 - (3 >> 3), (2 - 3) >> 3 union select * from v1;
+2 - 3 >> 3 2 - (3 >> 3) (2 - 3) >> 3
+2305843009213693951 2 2305843009213693951
+create or replace view v1 as select 2 - '2000-01-01' +INTERVAL 1 DAY, 2 - ('2000-01-01' +INTERVAL 1 DAY), (2 - '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - '2000-01-01' + interval 1 day AS `2 - '2000-01-01' +INTERVAL 1 DAY`,2 - ('2000-01-01' + interval 1 day) AS `2 - ('2000-01-01' +INTERVAL 1 DAY)`,2 - '2000-01-01' + interval 1 day AS `(2 - '2000-01-01') +INTERVAL 1 DAY`
+select 2 - '2000-01-01' +INTERVAL 1 DAY, 2 - ('2000-01-01' +INTERVAL 1 DAY), (2 - '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 - '2000-01-01' +INTERVAL 1 DAY 2 - ('2000-01-01' +INTERVAL 1 DAY) (2 - '2000-01-01') +INTERVAL 1 DAY
+NULL -20000100 NULL
+create or replace view v1 as select 2 - 3 + 3, 2 - (3 + 3), (2 - 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 + 3 AS `2 - 3 + 3`,2 - (3 + 3) AS `2 - (3 + 3)`,2 - 3 + 3 AS `(2 - 3) + 3`
+select 2 - 3 + 3, 2 - (3 + 3), (2 - 3) + 3 union select * from v1;
+2 - 3 + 3 2 - (3 + 3) (2 - 3) + 3
+2 -4 2
+create or replace view v1 as select 2 - 3 - 3, 2 - (3 - 3), (2 - 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 - 3 AS `2 - 3 - 3`,2 - (3 - 3) AS `2 - (3 - 3)`,2 - 3 - 3 AS `(2 - 3) - 3`
+select 2 - 3 - 3, 2 - (3 - 3), (2 - 3) - 3 union select * from v1;
+2 - 3 - 3 2 - (3 - 3) (2 - 3) - 3
+-4 2 -4
+create or replace view v1 as select 2 - 3 * 3, 2 - (3 * 3), (2 - 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 * 3 AS `2 - 3 * 3`,2 - 3 * 3 AS `2 - (3 * 3)`,(2 - 3) * 3 AS `(2 - 3) * 3`
+select 2 - 3 * 3, 2 - (3 * 3), (2 - 3) * 3 union select * from v1;
+2 - 3 * 3 2 - (3 * 3) (2 - 3) * 3
+-7 -7 -3
+create or replace view v1 as select 2 - 3 / 3, 2 - (3 / 3), (2 - 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 / 3 AS `2 - 3 / 3`,2 - 3 / 3 AS `2 - (3 / 3)`,(2 - 3) / 3 AS `(2 - 3) / 3`
+select 2 - 3 / 3, 2 - (3 / 3), (2 - 3) / 3 union select * from v1;
+2 - 3 / 3 2 - (3 / 3) (2 - 3) / 3
+1.0000 1.0000 -0.3333
+create or replace view v1 as select 2 - 3 DIV 3, 2 - (3 DIV 3), (2 - 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 DIV 3 AS `2 - 3 DIV 3`,2 - 3 DIV 3 AS `2 - (3 DIV 3)`,(2 - 3) DIV 3 AS `(2 - 3) DIV 3`
+select 2 - 3 DIV 3, 2 - (3 DIV 3), (2 - 3) DIV 3 union select * from v1;
+2 - 3 DIV 3 2 - (3 DIV 3) (2 - 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 - 3 MOD 3, 2 - (3 MOD 3), (2 - 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 MOD 3 AS `2 - 3 MOD 3`,2 - 3 MOD 3 AS `2 - (3 MOD 3)`,(2 - 3) MOD 3 AS `(2 - 3) MOD 3`
+select 2 - 3 MOD 3, 2 - (3 MOD 3), (2 - 3) MOD 3 union select * from v1;
+2 - 3 MOD 3 2 - (3 MOD 3) (2 - 3) MOD 3
+2 2 -1
+create or replace view v1 as select 2 - 3 % 3, 2 - (3 % 3), (2 - 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 MOD 3 AS `2 - 3 % 3`,2 - 3 MOD 3 AS `2 - (3 % 3)`,(2 - 3) MOD 3 AS `(2 - 3) % 3`
+select 2 - 3 % 3, 2 - (3 % 3), (2 - 3) % 3 union select * from v1;
+2 - 3 % 3 2 - (3 % 3) (2 - 3) % 3
+2 2 -1
+create or replace view v1 as select 2 - 3 ^ 3, 2 - (3 ^ 3), (2 - 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 ^ 3 AS `2 - 3 ^ 3`,2 - 3 ^ 3 AS `2 - (3 ^ 3)`,(2 - 3) ^ 3 AS `(2 - 3) ^ 3`
+select 2 - 3 ^ 3, 2 - (3 ^ 3), (2 - 3) ^ 3 union select * from v1;
+2 - 3 ^ 3 2 - (3 ^ 3) (2 - 3) ^ 3
+2 2 18446744073709551612
+create or replace view v1 as select 2 - 3 BETWEEN 1 AND 3, 2 - (3 BETWEEN 1 AND 3), (2 - 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 between 1 and 3 AS `2 - 3 BETWEEN 1 AND 3`,2 - (3 between 1 and 3) AS `2 - (3 BETWEEN 1 AND 3)`,2 - 3 between 1 and 3 AS `(2 - 3) BETWEEN 1 AND 3`
+select 2 - 3 BETWEEN 1 AND 3, 2 - (3 BETWEEN 1 AND 3), (2 - 3) BETWEEN 1 AND 3 union select * from v1;
+2 - 3 BETWEEN 1 AND 3 2 - (3 BETWEEN 1 AND 3) (2 - 3) BETWEEN 1 AND 3
+0 1 0
+create or replace view v1 as select 2 * 0 IS FALSE, 2 * (0 IS FALSE), (2 * 0) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 0 is false AS `2 * 0 IS FALSE`,2 * (0 is false) AS `2 * (0 IS FALSE)`,2 * 0 is false AS `(2 * 0) IS FALSE`
+select 2 * 0 IS FALSE, 2 * (0 IS FALSE), (2 * 0) IS FALSE union select * from v1;
+2 * 0 IS FALSE 2 * (0 IS FALSE) (2 * 0) IS FALSE
+1 2 1
+create or replace view v1 as select charset(2 * 3 COLLATE latin1_bin), charset(2 * (3 COLLATE latin1_bin)), charset((2 * 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 * 3 collate latin1_bin) AS `charset(2 * 3 COLLATE latin1_bin)`,charset(2 * 3 collate latin1_bin) AS `charset(2 * (3 COLLATE latin1_bin))`,charset((2 * 3) collate latin1_bin) AS `charset((2 * 3) COLLATE latin1_bin)`
+select charset(2 * 3 COLLATE latin1_bin), charset(2 * (3 COLLATE latin1_bin)), charset((2 * 3) COLLATE latin1_bin) union select * from v1;
+charset(2 * 3 COLLATE latin1_bin) charset(2 * (3 COLLATE latin1_bin)) charset((2 * 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 * 0 IN (0,1), 2 * (0 IN (0,1)), (2 * 0) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 0 in (0,1) AS `2 * 0 IN (0,1)`,2 * (0 in (0,1)) AS `2 * (0 IN (0,1))`,2 * 0 in (0,1) AS `(2 * 0) IN (0,1)`
+select 2 * 0 IN (0,1), 2 * (0 IN (0,1)), (2 * 0) IN (0,1) union select * from v1;
+2 * 0 IN (0,1) 2 * (0 IN (0,1)) (2 * 0) IN (0,1)
+1 2 1
+create or replace view v1 as select 2 * 3 OR 3, 2 * (3 OR 3), (2 * 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 or 3 AS `2 * 3 OR 3`,2 * (3 or 3) AS `2 * (3 OR 3)`,2 * 3 or 3 AS `(2 * 3) OR 3`
+select 2 * 3 OR 3, 2 * (3 OR 3), (2 * 3) OR 3 union select * from v1;
+2 * 3 OR 3 2 * (3 OR 3) (2 * 3) OR 3
+1 2 1
+create or replace view v1 as select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 or 3 AS `2 * 3 || 3`,2 * (3 or 3) AS `2 * (3 || 3)`,2 * 3 or 3 AS `(2 * 3) || 3`
+select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3 union select * from v1;
+2 * 3 || 3 2 * (3 || 3) (2 * 3) || 3
+1 2 1
+create or replace view v1 as select 2 * 3 XOR 0, 2 * (3 XOR 0), (2 * 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 xor 0 AS `2 * 3 XOR 0`,2 * (3 xor 0) AS `2 * (3 XOR 0)`,2 * 3 xor 0 AS `(2 * 3) XOR 0`
+select 2 * 3 XOR 0, 2 * (3 XOR 0), (2 * 3) XOR 0 union select * from v1;
+2 * 3 XOR 0 2 * (3 XOR 0) (2 * 3) XOR 0
+1 2 1
+create or replace view v1 as select 2 * 3 AND 3, 2 * (3 AND 3), (2 * 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 and 3 AS `2 * 3 AND 3`,2 * (3 and 3) AS `2 * (3 AND 3)`,2 * 3 and 3 AS `(2 * 3) AND 3`
+select 2 * 3 AND 3, 2 * (3 AND 3), (2 * 3) AND 3 union select * from v1;
+2 * 3 AND 3 2 * (3 AND 3) (2 * 3) AND 3
+1 2 1
+create or replace view v1 as select 2 * 3 && 3, 2 * (3 && 3), (2 * 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 and 3 AS `2 * 3 && 3`,2 * (3 and 3) AS `2 * (3 && 3)`,2 * 3 and 3 AS `(2 * 3) && 3`
+select 2 * 3 && 3, 2 * (3 && 3), (2 * 3) && 3 union select * from v1;
+2 * 3 && 3 2 * (3 && 3) (2 * 3) && 3
+1 2 1
+create or replace view v1 as select 2 * 3 = 3, 2 * (3 = 3), (2 * 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 = 3 AS `2 * 3 = 3`,2 * (3 = 3) AS `2 * (3 = 3)`,2 * 3 = 3 AS `(2 * 3) = 3`
+select 2 * 3 = 3, 2 * (3 = 3), (2 * 3) = 3 union select * from v1;
+2 * 3 = 3 2 * (3 = 3) (2 * 3) = 3
+0 2 0
+create or replace view v1 as select 2 * 3 <=> 3, 2 * (3 <=> 3), (2 * 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 <=> 3 AS `2 * 3 <=> 3`,2 * (3 <=> 3) AS `2 * (3 <=> 3)`,2 * 3 <=> 3 AS `(2 * 3) <=> 3`
+select 2 * 3 <=> 3, 2 * (3 <=> 3), (2 * 3) <=> 3 union select * from v1;
+2 * 3 <=> 3 2 * (3 <=> 3) (2 * 3) <=> 3
+0 2 0
+create or replace view v1 as select 2 * 3 >= 3, 2 * (3 >= 3), (2 * 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 >= 3 AS `2 * 3 >= 3`,2 * (3 >= 3) AS `2 * (3 >= 3)`,2 * 3 >= 3 AS `(2 * 3) >= 3`
+select 2 * 3 >= 3, 2 * (3 >= 3), (2 * 3) >= 3 union select * from v1;
+2 * 3 >= 3 2 * (3 >= 3) (2 * 3) >= 3
+1 2 1
+create or replace view v1 as select 2 * 3 <= 3, 2 * (3 <= 3), (2 * 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 <= 3 AS `2 * 3 <= 3`,2 * (3 <= 3) AS `2 * (3 <= 3)`,2 * 3 <= 3 AS `(2 * 3) <= 3`
+select 2 * 3 <= 3, 2 * (3 <= 3), (2 * 3) <= 3 union select * from v1;
+2 * 3 <= 3 2 * (3 <= 3) (2 * 3) <= 3
+0 2 0
+create or replace view v1 as select 2 * 0 < 3, 2 * (0 < 3), (2 * 0) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 0 < 3 AS `2 * 0 < 3`,2 * (0 < 3) AS `2 * (0 < 3)`,2 * 0 < 3 AS `(2 * 0) < 3`
+select 2 * 0 < 3, 2 * (0 < 3), (2 * 0) < 3 union select * from v1;
+2 * 0 < 3 2 * (0 < 3) (2 * 0) < 3
+1 2 1
+create or replace view v1 as select 2 * 3 <> 3, 2 * (3 <> 3), (2 * 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 <> 3 AS `2 * 3 <> 3`,2 * (3 <> 3) AS `2 * (3 <> 3)`,2 * 3 <> 3 AS `(2 * 3) <> 3`
+select 2 * 3 <> 3, 2 * (3 <> 3), (2 * 3) <> 3 union select * from v1;
+2 * 3 <> 3 2 * (3 <> 3) (2 * 3) <> 3
+1 0 1
+create or replace view v1 as select 2 * 3 > 3, 2 * (3 > 3), (2 * 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 > 3 AS `2 * 3 > 3`,2 * (3 > 3) AS `2 * (3 > 3)`,2 * 3 > 3 AS `(2 * 3) > 3`
+select 2 * 3 > 3, 2 * (3 > 3), (2 * 3) > 3 union select * from v1;
+2 * 3 > 3 2 * (3 > 3) (2 * 3) > 3
+1 0 1
+create or replace view v1 as select 2 * 3 != 3, 2 * (3 != 3), (2 * 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 <> 3 AS `2 * 3 != 3`,2 * (3 <> 3) AS `2 * (3 != 3)`,2 * 3 <> 3 AS `(2 * 3) != 3`
+select 2 * 3 != 3, 2 * (3 != 3), (2 * 3) != 3 union select * from v1;
+2 * 3 != 3 2 * (3 != 3) (2 * 3) != 3
+1 0 1
+create or replace view v1 as select 2 * 3 LIKE 3, 2 * (3 LIKE 3), (2 * 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 like 3 AS `2 * 3 LIKE 3`,2 * (3 like 3) AS `2 * (3 LIKE 3)`,2 * 3 like 3 AS `(2 * 3) LIKE 3`
+select 2 * 3 LIKE 3, 2 * (3 LIKE 3), (2 * 3) LIKE 3 union select * from v1;
+2 * 3 LIKE 3 2 * (3 LIKE 3) (2 * 3) LIKE 3
+0 2 0
+create or replace view v1 as select 2 * 3 REGEXP 3, 2 * (3 REGEXP 3), (2 * 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 regexp 3 AS `2 * 3 REGEXP 3`,2 * (3 regexp 3) AS `2 * (3 REGEXP 3)`,2 * 3 regexp 3 AS `(2 * 3) REGEXP 3`
+select 2 * 3 REGEXP 3, 2 * (3 REGEXP 3), (2 * 3) REGEXP 3 union select * from v1;
+2 * 3 REGEXP 3 2 * (3 REGEXP 3) (2 * 3) REGEXP 3
+0 2 0
+create or replace view v1 as select 2 * 3 | 3, 2 * (3 | 3), (2 * 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 | 3 AS `2 * 3 | 3`,2 * (3 | 3) AS `2 * (3 | 3)`,2 * 3 | 3 AS `(2 * 3) | 3`
+select 2 * 3 | 3, 2 * (3 | 3), (2 * 3) | 3 union select * from v1;
+2 * 3 | 3 2 * (3 | 3) (2 * 3) | 3
+7 6 7
+create or replace view v1 as select 2 * 3 & 3, 2 * (3 & 3), (2 * 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 & 3 AS `2 * 3 & 3`,2 * (3 & 3) AS `2 * (3 & 3)`,2 * 3 & 3 AS `(2 * 3) & 3`
+select 2 * 3 & 3, 2 * (3 & 3), (2 * 3) & 3 union select * from v1;
+2 * 3 & 3 2 * (3 & 3) (2 * 3) & 3
+2 6 2
+create or replace view v1 as select 2 * 3 >> 2, 2 * (3 >> 2), (2 * 3) >> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 >> 2 AS `2 * 3 >> 2`,2 * (3 >> 2) AS `2 * (3 >> 2)`,2 * 3 >> 2 AS `(2 * 3) >> 2`
+select 2 * 3 >> 2, 2 * (3 >> 2), (2 * 3) >> 2 union select * from v1;
+2 * 3 >> 2 2 * (3 >> 2) (2 * 3) >> 2
+1 0 1
+create or replace view v1 as select 2 * '2000-01-01' +INTERVAL 1 DAY, 2 * ('2000-01-01' +INTERVAL 1 DAY), (2 * '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * '2000-01-01' + interval 1 day AS `2 * '2000-01-01' +INTERVAL 1 DAY`,2 * ('2000-01-01' + interval 1 day) AS `2 * ('2000-01-01' +INTERVAL 1 DAY)`,2 * '2000-01-01' + interval 1 day AS `(2 * '2000-01-01') +INTERVAL 1 DAY`
+select 2 * '2000-01-01' +INTERVAL 1 DAY, 2 * ('2000-01-01' +INTERVAL 1 DAY), (2 * '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 * '2000-01-01' +INTERVAL 1 DAY 2 * ('2000-01-01' +INTERVAL 1 DAY) (2 * '2000-01-01') +INTERVAL 1 DAY
+NULL 40000204 NULL
+create or replace view v1 as select 2 * 3 + 3, 2 * (3 + 3), (2 * 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 + 3 AS `2 * 3 + 3`,2 * (3 + 3) AS `2 * (3 + 3)`,2 * 3 + 3 AS `(2 * 3) + 3`
+select 2 * 3 + 3, 2 * (3 + 3), (2 * 3) + 3 union select * from v1;
+2 * 3 + 3 2 * (3 + 3) (2 * 3) + 3
+9 12 9
+create or replace view v1 as select 2 * 3 - 3, 2 * (3 - 3), (2 * 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 - 3 AS `2 * 3 - 3`,2 * (3 - 3) AS `2 * (3 - 3)`,2 * 3 - 3 AS `(2 * 3) - 3`
+select 2 * 3 - 3, 2 * (3 - 3), (2 * 3) - 3 union select * from v1;
+2 * 3 - 3 2 * (3 - 3) (2 * 3) - 3
+3 0 3
+create or replace view v1 as select 2 * 3 DIV 2, 2 * (3 DIV 2), (2 * 3) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 DIV 2 AS `2 * 3 DIV 2`,2 * (3 DIV 2) AS `2 * (3 DIV 2)`,2 * 3 DIV 2 AS `(2 * 3) DIV 2`
+select 2 * 3 DIV 2, 2 * (3 DIV 2), (2 * 3) DIV 2 union select * from v1;
+2 * 3 DIV 2 2 * (3 DIV 2) (2 * 3) DIV 2
+3 2 3
+create or replace view v1 as select 2 * 3 MOD 2, 2 * (3 MOD 2), (2 * 3) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 MOD 2 AS `2 * 3 MOD 2`,2 * (3 MOD 2) AS `2 * (3 MOD 2)`,2 * 3 MOD 2 AS `(2 * 3) MOD 2`
+select 2 * 3 MOD 2, 2 * (3 MOD 2), (2 * 3) MOD 2 union select * from v1;
+2 * 3 MOD 2 2 * (3 MOD 2) (2 * 3) MOD 2
+0 2 0
+create or replace view v1 as select 2 * 3 % 2, 2 * (3 % 2), (2 * 3) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 MOD 2 AS `2 * 3 % 2`,2 * (3 MOD 2) AS `2 * (3 % 2)`,2 * 3 MOD 2 AS `(2 * 3) % 2`
+select 2 * 3 % 2, 2 * (3 % 2), (2 * 3) % 2 union select * from v1;
+2 * 3 % 2 2 * (3 % 2) (2 * 3) % 2
+0 2 0
+create or replace view v1 as select 2 * 3 ^ 3, 2 * (3 ^ 3), (2 * 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 ^ 3 AS `2 * 3 ^ 3`,2 * 3 ^ 3 AS `2 * (3 ^ 3)`,(2 * 3) ^ 3 AS `(2 * 3) ^ 3`
+select 2 * 3 ^ 3, 2 * (3 ^ 3), (2 * 3) ^ 3 union select * from v1;
+2 * 3 ^ 3 2 * (3 ^ 3) (2 * 3) ^ 3
+0 0 5
+create or replace view v1 as select 2 * 3 BETWEEN 1 AND 3, 2 * (3 BETWEEN 1 AND 3), (2 * 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 3 between 1 and 3 AS `2 * 3 BETWEEN 1 AND 3`,2 * (3 between 1 and 3) AS `2 * (3 BETWEEN 1 AND 3)`,2 * 3 between 1 and 3 AS `(2 * 3) BETWEEN 1 AND 3`
+select 2 * 3 BETWEEN 1 AND 3, 2 * (3 BETWEEN 1 AND 3), (2 * 3) BETWEEN 1 AND 3 union select * from v1;
+2 * 3 BETWEEN 1 AND 3 2 * (3 BETWEEN 1 AND 3) (2 * 3) BETWEEN 1 AND 3
+0 2 0
+create or replace view v1 as select 2 / 3 IS FALSE, 2 / (3 IS FALSE), (2 / 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 is false AS `2 / 3 IS FALSE`,2 / (3 is false) AS `2 / (3 IS FALSE)`,2 / 3 is false AS `(2 / 3) IS FALSE`
+select 2 / 3 IS FALSE, 2 / (3 IS FALSE), (2 / 3) IS FALSE union select * from v1;
+2 / 3 IS FALSE 2 / (3 IS FALSE) (2 / 3) IS FALSE
+0 NULL 0
+create or replace view v1 as select charset(2 / 3 COLLATE latin1_bin), charset(2 / (3 COLLATE latin1_bin)), charset((2 / 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 / 3 collate latin1_bin) AS `charset(2 / 3 COLLATE latin1_bin)`,charset(2 / 3 collate latin1_bin) AS `charset(2 / (3 COLLATE latin1_bin))`,charset((2 / 3) collate latin1_bin) AS `charset((2 / 3) COLLATE latin1_bin)`
+select charset(2 / 3 COLLATE latin1_bin), charset(2 / (3 COLLATE latin1_bin)), charset((2 / 3) COLLATE latin1_bin) union select * from v1;
+charset(2 / 3 COLLATE latin1_bin) charset(2 / (3 COLLATE latin1_bin)) charset((2 / 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 / 3 IN (0,1), 2 / (3 IN (0,1)), (2 / 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 in (0,1) AS `2 / 3 IN (0,1)`,2 / (3 in (0,1)) AS `2 / (3 IN (0,1))`,2 / 3 in (0,1) AS `(2 / 3) IN (0,1)`
+select 2 / 3 IN (0,1), 2 / (3 IN (0,1)), (2 / 3) IN (0,1) union select * from v1;
+2 / 3 IN (0,1) 2 / (3 IN (0,1)) (2 / 3) IN (0,1)
+0 NULL 0
+create or replace view v1 as select 2 / 3 OR 3, 2 / (3 OR 3), (2 / 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 or 3 AS `2 / 3 OR 3`,2 / (3 or 3) AS `2 / (3 OR 3)`,2 / 3 or 3 AS `(2 / 3) OR 3`
+select 2 / 3 OR 3, 2 / (3 OR 3), (2 / 3) OR 3 union select * from v1;
+2 / 3 OR 3 2 / (3 OR 3) (2 / 3) OR 3
+1 2.0000 1
+create or replace view v1 as select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 or 3 AS `2 / 3 || 3`,2 / (3 or 3) AS `2 / (3 || 3)`,2 / 3 or 3 AS `(2 / 3) || 3`
+select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3 union select * from v1;
+2 / 3 || 3 2 / (3 || 3) (2 / 3) || 3
+1 2.0000 1
+create or replace view v1 as select 2 / 3 XOR 3, 2 / (3 XOR 3), (2 / 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 xor 3 AS `2 / 3 XOR 3`,2 / (3 xor 3) AS `2 / (3 XOR 3)`,2 / 3 xor 3 AS `(2 / 3) XOR 3`
+select 2 / 3 XOR 3, 2 / (3 XOR 3), (2 / 3) XOR 3 union select * from v1;
+2 / 3 XOR 3 2 / (3 XOR 3) (2 / 3) XOR 3
+0 NULL 0
+create or replace view v1 as select 2 / 3 AND 3, 2 / (3 AND 3), (2 / 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 and 3 AS `2 / 3 AND 3`,2 / (3 and 3) AS `2 / (3 AND 3)`,2 / 3 and 3 AS `(2 / 3) AND 3`
+select 2 / 3 AND 3, 2 / (3 AND 3), (2 / 3) AND 3 union select * from v1;
+2 / 3 AND 3 2 / (3 AND 3) (2 / 3) AND 3
+1 2.0000 1
+create or replace view v1 as select 2 / 3 && 3, 2 / (3 && 3), (2 / 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 and 3 AS `2 / 3 && 3`,2 / (3 and 3) AS `2 / (3 && 3)`,2 / 3 and 3 AS `(2 / 3) && 3`
+select 2 / 3 && 3, 2 / (3 && 3), (2 / 3) && 3 union select * from v1;
+2 / 3 && 3 2 / (3 && 3) (2 / 3) && 3
+1 2.0000 1
+create or replace view v1 as select 2 / 3 = 3, 2 / (3 = 3), (2 / 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 = 3 AS `2 / 3 = 3`,2 / (3 = 3) AS `2 / (3 = 3)`,2 / 3 = 3 AS `(2 / 3) = 3`
+select 2 / 3 = 3, 2 / (3 = 3), (2 / 3) = 3 union select * from v1;
+2 / 3 = 3 2 / (3 = 3) (2 / 3) = 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 <=> 3, 2 / (3 <=> 3), (2 / 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 <=> 3 AS `2 / 3 <=> 3`,2 / (3 <=> 3) AS `2 / (3 <=> 3)`,2 / 3 <=> 3 AS `(2 / 3) <=> 3`
+select 2 / 3 <=> 3, 2 / (3 <=> 3), (2 / 3) <=> 3 union select * from v1;
+2 / 3 <=> 3 2 / (3 <=> 3) (2 / 3) <=> 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 >= 3, 2 / (3 >= 3), (2 / 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 >= 3 AS `2 / 3 >= 3`,2 / (3 >= 3) AS `2 / (3 >= 3)`,2 / 3 >= 3 AS `(2 / 3) >= 3`
+select 2 / 3 >= 3, 2 / (3 >= 3), (2 / 3) >= 3 union select * from v1;
+2 / 3 >= 3 2 / (3 >= 3) (2 / 3) >= 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 <= 3, 2 / (3 <= 3), (2 / 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 <= 3 AS `2 / 3 <= 3`,2 / (3 <= 3) AS `2 / (3 <= 3)`,2 / 3 <= 3 AS `(2 / 3) <= 3`
+select 2 / 3 <= 3, 2 / (3 <= 3), (2 / 3) <= 3 union select * from v1;
+2 / 3 <= 3 2 / (3 <= 3) (2 / 3) <= 3
+1 2.0000 1
+create or replace view v1 as select 2 / 3 < 3, 2 / (3 < 3), (2 / 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 < 3 AS `2 / 3 < 3`,2 / (3 < 3) AS `2 / (3 < 3)`,2 / 3 < 3 AS `(2 / 3) < 3`
+select 2 / 3 < 3, 2 / (3 < 3), (2 / 3) < 3 union select * from v1;
+2 / 3 < 3 2 / (3 < 3) (2 / 3) < 3
+1 NULL 1
+create or replace view v1 as select 2 / 3 <> 3, 2 / (3 <> 3), (2 / 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 <> 3 AS `2 / 3 <> 3`,2 / (3 <> 3) AS `2 / (3 <> 3)`,2 / 3 <> 3 AS `(2 / 3) <> 3`
+select 2 / 3 <> 3, 2 / (3 <> 3), (2 / 3) <> 3 union select * from v1;
+2 / 3 <> 3 2 / (3 <> 3) (2 / 3) <> 3
+1 NULL 1
+create or replace view v1 as select 2 / 3 > 3, 2 / (3 > 3), (2 / 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 > 3 AS `2 / 3 > 3`,2 / (3 > 3) AS `2 / (3 > 3)`,2 / 3 > 3 AS `(2 / 3) > 3`
+select 2 / 3 > 3, 2 / (3 > 3), (2 / 3) > 3 union select * from v1;
+2 / 3 > 3 2 / (3 > 3) (2 / 3) > 3
+0 NULL 0
+create or replace view v1 as select 2 / 3 != 3, 2 / (3 != 3), (2 / 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 <> 3 AS `2 / 3 != 3`,2 / (3 <> 3) AS `2 / (3 != 3)`,2 / 3 <> 3 AS `(2 / 3) != 3`
+select 2 / 3 != 3, 2 / (3 != 3), (2 / 3) != 3 union select * from v1;
+2 / 3 != 3 2 / (3 != 3) (2 / 3) != 3
+1 NULL 1
+create or replace view v1 as select 2 / 3 LIKE 3, 2 / (3 LIKE 3), (2 / 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 like 3 AS `2 / 3 LIKE 3`,2 / (3 like 3) AS `2 / (3 LIKE 3)`,2 / 3 like 3 AS `(2 / 3) LIKE 3`
+select 2 / 3 LIKE 3, 2 / (3 LIKE 3), (2 / 3) LIKE 3 union select * from v1;
+2 / 3 LIKE 3 2 / (3 LIKE 3) (2 / 3) LIKE 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 REGEXP 3, 2 / (3 REGEXP 3), (2 / 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 regexp 3 AS `2 / 3 REGEXP 3`,2 / (3 regexp 3) AS `2 / (3 REGEXP 3)`,2 / 3 regexp 3 AS `(2 / 3) REGEXP 3`
+select 2 / 3 REGEXP 3, 2 / (3 REGEXP 3), (2 / 3) REGEXP 3 union select * from v1;
+2 / 3 REGEXP 3 2 / (3 REGEXP 3) (2 / 3) REGEXP 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 | 3, 2 / (3 | 3), (2 / 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 | 3 AS `2 / 3 | 3`,2 / (3 | 3) AS `2 / (3 | 3)`,2 / 3 | 3 AS `(2 / 3) | 3`
+select 2 / 3 | 3, 2 / (3 | 3), (2 / 3) | 3 union select * from v1;
+2 / 3 | 3 2 / (3 | 3) (2 / 3) | 3
+3 0.6667 3
+create or replace view v1 as select 2 / 3 & 3, 2 / (3 & 3), (2 / 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 & 3 AS `2 / 3 & 3`,2 / (3 & 3) AS `2 / (3 & 3)`,2 / 3 & 3 AS `(2 / 3) & 3`
+select 2 / 3 & 3, 2 / (3 & 3), (2 / 3) & 3 union select * from v1;
+2 / 3 & 3 2 / (3 & 3) (2 / 3) & 3
+1 0.6667 1
+create or replace view v1 as select 2 / 3 << 3, 2 / (3 << 3), (2 / 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 << 3 AS `2 / 3 << 3`,2 / (3 << 3) AS `2 / (3 << 3)`,2 / 3 << 3 AS `(2 / 3) << 3`
+select 2 / 3 << 3, 2 / (3 << 3), (2 / 3) << 3 union select * from v1;
+2 / 3 << 3 2 / (3 << 3) (2 / 3) << 3
+8 0.0833 8
+create or replace view v1 as select 2 / 3 >> 3, 2 / (3 >> 3), (2 / 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 >> 3 AS `2 / 3 >> 3`,2 / (3 >> 3) AS `2 / (3 >> 3)`,2 / 3 >> 3 AS `(2 / 3) >> 3`
+select 2 / 3 >> 3, 2 / (3 >> 3), (2 / 3) >> 3 union select * from v1;
+2 / 3 >> 3 2 / (3 >> 3) (2 / 3) >> 3
+0 NULL 0
+create or replace view v1 as select 2 / '2000-01-01' +INTERVAL 1 DAY, 2 / ('2000-01-01' +INTERVAL 1 DAY), (2 / '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / '2000-01-01' + interval 1 day AS `2 / '2000-01-01' +INTERVAL 1 DAY`,2 / ('2000-01-01' + interval 1 day) AS `2 / ('2000-01-01' +INTERVAL 1 DAY)`,2 / '2000-01-01' + interval 1 day AS `(2 / '2000-01-01') +INTERVAL 1 DAY`
+select 2 / '2000-01-01' +INTERVAL 1 DAY, 2 / ('2000-01-01' +INTERVAL 1 DAY), (2 / '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 / '2000-01-01' +INTERVAL 1 DAY 2 / ('2000-01-01' +INTERVAL 1 DAY) (2 / '2000-01-01') +INTERVAL 1 DAY
+NULL 0.0000 NULL
+create or replace view v1 as select 2 / 3 + 3, 2 / (3 + 3), (2 / 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 + 3 AS `2 / 3 + 3`,2 / (3 + 3) AS `2 / (3 + 3)`,2 / 3 + 3 AS `(2 / 3) + 3`
+select 2 / 3 + 3, 2 / (3 + 3), (2 / 3) + 3 union select * from v1;
+2 / 3 + 3 2 / (3 + 3) (2 / 3) + 3
+3.6667 0.3333 3.6667
+create or replace view v1 as select 2 / 3 - 3, 2 / (3 - 3), (2 / 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 - 3 AS `2 / 3 - 3`,2 / (3 - 3) AS `2 / (3 - 3)`,2 / 3 - 3 AS `(2 / 3) - 3`
+select 2 / 3 - 3, 2 / (3 - 3), (2 / 3) - 3 union select * from v1;
+2 / 3 - 3 2 / (3 - 3) (2 / 3) - 3
+-2.3333 NULL -2.3333
+create or replace view v1 as select 2 / 3 * 3, 2 / (3 * 3), (2 / 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 * 3 AS `2 / 3 * 3`,2 / (3 * 3) AS `2 / (3 * 3)`,2 / 3 * 3 AS `(2 / 3) * 3`
+select 2 / 3 * 3, 2 / (3 * 3), (2 / 3) * 3 union select * from v1;
+2 / 3 * 3 2 / (3 * 3) (2 / 3) * 3
+2.0000 0.2222 2.0000
+create or replace view v1 as select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 / 3 AS `2 / 3 / 3`,2 / (3 / 3) AS `2 / (3 / 3)`,2 / 3 / 3 AS `(2 / 3) / 3`
+select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3 union select * from v1;
+2 / 3 / 3 2 / (3 / 3) (2 / 3) / 3
+0.22222222 2.0000 0.22222222
+create or replace view v1 as select 2 / 3 DIV 3, 2 / (3 DIV 3), (2 / 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 DIV 3 AS `2 / 3 DIV 3`,2 / (3 DIV 3) AS `2 / (3 DIV 3)`,2 / 3 DIV 3 AS `(2 / 3) DIV 3`
+select 2 / 3 DIV 3, 2 / (3 DIV 3), (2 / 3) DIV 3 union select * from v1;
+2 / 3 DIV 3 2 / (3 DIV 3) (2 / 3) DIV 3
+0 2.0000 0
+create or replace view v1 as select 2 / 3 MOD 3, 2 / (3 MOD 3), (2 / 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 MOD 3 AS `2 / 3 MOD 3`,2 / (3 MOD 3) AS `2 / (3 MOD 3)`,2 / 3 MOD 3 AS `(2 / 3) MOD 3`
+select 2 / 3 MOD 3, 2 / (3 MOD 3), (2 / 3) MOD 3 union select * from v1;
+2 / 3 MOD 3 2 / (3 MOD 3) (2 / 3) MOD 3
+0.6667 NULL 0.6667
+create or replace view v1 as select 2 / 3 % 3, 2 / (3 % 3), (2 / 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 MOD 3 AS `2 / 3 % 3`,2 / (3 MOD 3) AS `2 / (3 % 3)`,2 / 3 MOD 3 AS `(2 / 3) % 3`
+select 2 / 3 % 3, 2 / (3 % 3), (2 / 3) % 3 union select * from v1;
+2 / 3 % 3 2 / (3 % 3) (2 / 3) % 3
+0.6667 NULL 0.6667
+create or replace view v1 as select 2 / 3 ^ 3, 2 / (3 ^ 3), (2 / 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 ^ 3 AS `2 / 3 ^ 3`,2 / 3 ^ 3 AS `2 / (3 ^ 3)`,(2 / 3) ^ 3 AS `(2 / 3) ^ 3`
+select 2 / 3 ^ 3, 2 / (3 ^ 3), (2 / 3) ^ 3 union select * from v1;
+2 / 3 ^ 3 2 / (3 ^ 3) (2 / 3) ^ 3
+NULL NULL 2
+create or replace view v1 as select 2 / 3 BETWEEN 1 AND 3, 2 / (3 BETWEEN 1 AND 3), (2 / 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 between 1 and 3 AS `2 / 3 BETWEEN 1 AND 3`,2 / (3 between 1 and 3) AS `2 / (3 BETWEEN 1 AND 3)`,2 / 3 between 1 and 3 AS `(2 / 3) BETWEEN 1 AND 3`
+select 2 / 3 BETWEEN 1 AND 3, 2 / (3 BETWEEN 1 AND 3), (2 / 3) BETWEEN 1 AND 3 union select * from v1;
+2 / 3 BETWEEN 1 AND 3 2 / (3 BETWEEN 1 AND 3) (2 / 3) BETWEEN 1 AND 3
+0 2.0000 0
+create or replace view v1 as select 2 DIV 3 IS FALSE, 2 DIV (3 IS FALSE), (2 DIV 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 is false AS `2 DIV 3 IS FALSE`,2 DIV (3 is false) AS `2 DIV (3 IS FALSE)`,2 DIV 3 is false AS `(2 DIV 3) IS FALSE`
+select 2 DIV 3 IS FALSE, 2 DIV (3 IS FALSE), (2 DIV 3) IS FALSE union select * from v1;
+2 DIV 3 IS FALSE 2 DIV (3 IS FALSE) (2 DIV 3) IS FALSE
+1 NULL 1
+create or replace view v1 as select charset(2 DIV 3 COLLATE latin1_bin), charset(2 DIV (3 COLLATE latin1_bin)), charset((2 DIV 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 DIV 3 collate latin1_bin) AS `charset(2 DIV 3 COLLATE latin1_bin)`,charset(2 DIV 3 collate latin1_bin) AS `charset(2 DIV (3 COLLATE latin1_bin))`,charset((2 DIV 3) collate latin1_bin) AS `charset((2 DIV 3) COLLATE latin1_bin)`
+select charset(2 DIV 3 COLLATE latin1_bin), charset(2 DIV (3 COLLATE latin1_bin)), charset((2 DIV 3) COLLATE latin1_bin) union select * from v1;
+charset(2 DIV 3 COLLATE latin1_bin) charset(2 DIV (3 COLLATE latin1_bin)) charset((2 DIV 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 DIV 3 IN (0,1), 2 DIV (3 IN (0,1)), (2 DIV 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 in (0,1) AS `2 DIV 3 IN (0,1)`,2 DIV (3 in (0,1)) AS `2 DIV (3 IN (0,1))`,2 DIV 3 in (0,1) AS `(2 DIV 3) IN (0,1)`
+select 2 DIV 3 IN (0,1), 2 DIV (3 IN (0,1)), (2 DIV 3) IN (0,1) union select * from v1;
+2 DIV 3 IN (0,1) 2 DIV (3 IN (0,1)) (2 DIV 3) IN (0,1)
+1 NULL 1
+create or replace view v1 as select 2 DIV 3 OR 3, 2 DIV (3 OR 3), (2 DIV 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 or 3 AS `2 DIV 3 OR 3`,2 DIV (3 or 3) AS `2 DIV (3 OR 3)`,2 DIV 3 or 3 AS `(2 DIV 3) OR 3`
+select 2 DIV 3 OR 3, 2 DIV (3 OR 3), (2 DIV 3) OR 3 union select * from v1;
+2 DIV 3 OR 3 2 DIV (3 OR 3) (2 DIV 3) OR 3
+1 2 1
+create or replace view v1 as select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 or 3 AS `2 DIV 3 || 3`,2 DIV (3 or 3) AS `2 DIV (3 || 3)`,2 DIV 3 or 3 AS `(2 DIV 3) || 3`
+select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3 union select * from v1;
+2 DIV 3 || 3 2 DIV (3 || 3) (2 DIV 3) || 3
+1 2 1
+create or replace view v1 as select 2 DIV 3 XOR 3, 2 DIV (3 XOR 3), (2 DIV 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 xor 3 AS `2 DIV 3 XOR 3`,2 DIV (3 xor 3) AS `2 DIV (3 XOR 3)`,2 DIV 3 xor 3 AS `(2 DIV 3) XOR 3`
+select 2 DIV 3 XOR 3, 2 DIV (3 XOR 3), (2 DIV 3) XOR 3 union select * from v1;
+2 DIV 3 XOR 3 2 DIV (3 XOR 3) (2 DIV 3) XOR 3
+1 NULL 1
+create or replace view v1 as select 2 DIV 3 AND 3, 2 DIV (3 AND 3), (2 DIV 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 and 3 AS `2 DIV 3 AND 3`,2 DIV (3 and 3) AS `2 DIV (3 AND 3)`,2 DIV 3 and 3 AS `(2 DIV 3) AND 3`
+select 2 DIV 3 AND 3, 2 DIV (3 AND 3), (2 DIV 3) AND 3 union select * from v1;
+2 DIV 3 AND 3 2 DIV (3 AND 3) (2 DIV 3) AND 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 && 3, 2 DIV (3 && 3), (2 DIV 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 and 3 AS `2 DIV 3 && 3`,2 DIV (3 and 3) AS `2 DIV (3 && 3)`,2 DIV 3 and 3 AS `(2 DIV 3) && 3`
+select 2 DIV 3 && 3, 2 DIV (3 && 3), (2 DIV 3) && 3 union select * from v1;
+2 DIV 3 && 3 2 DIV (3 && 3) (2 DIV 3) && 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 = 3, 2 DIV (3 = 3), (2 DIV 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 = 3 AS `2 DIV 3 = 3`,2 DIV (3 = 3) AS `2 DIV (3 = 3)`,2 DIV 3 = 3 AS `(2 DIV 3) = 3`
+select 2 DIV 3 = 3, 2 DIV (3 = 3), (2 DIV 3) = 3 union select * from v1;
+2 DIV 3 = 3 2 DIV (3 = 3) (2 DIV 3) = 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 <=> 3, 2 DIV (3 <=> 3), (2 DIV 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 <=> 3 AS `2 DIV 3 <=> 3`,2 DIV (3 <=> 3) AS `2 DIV (3 <=> 3)`,2 DIV 3 <=> 3 AS `(2 DIV 3) <=> 3`
+select 2 DIV 3 <=> 3, 2 DIV (3 <=> 3), (2 DIV 3) <=> 3 union select * from v1;
+2 DIV 3 <=> 3 2 DIV (3 <=> 3) (2 DIV 3) <=> 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 >= 3, 2 DIV (3 >= 3), (2 DIV 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 >= 3 AS `2 DIV 3 >= 3`,2 DIV (3 >= 3) AS `2 DIV (3 >= 3)`,2 DIV 3 >= 3 AS `(2 DIV 3) >= 3`
+select 2 DIV 3 >= 3, 2 DIV (3 >= 3), (2 DIV 3) >= 3 union select * from v1;
+2 DIV 3 >= 3 2 DIV (3 >= 3) (2 DIV 3) >= 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 <= 3, 2 DIV (3 <= 3), (2 DIV 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 <= 3 AS `2 DIV 3 <= 3`,2 DIV (3 <= 3) AS `2 DIV (3 <= 3)`,2 DIV 3 <= 3 AS `(2 DIV 3) <= 3`
+select 2 DIV 3 <= 3, 2 DIV (3 <= 3), (2 DIV 3) <= 3 union select * from v1;
+2 DIV 3 <= 3 2 DIV (3 <= 3) (2 DIV 3) <= 3
+1 2 1
+create or replace view v1 as select 2 DIV 3 < 3, 2 DIV (3 < 3), (2 DIV 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 < 3 AS `2 DIV 3 < 3`,2 DIV (3 < 3) AS `2 DIV (3 < 3)`,2 DIV 3 < 3 AS `(2 DIV 3) < 3`
+select 2 DIV 3 < 3, 2 DIV (3 < 3), (2 DIV 3) < 3 union select * from v1;
+2 DIV 3 < 3 2 DIV (3 < 3) (2 DIV 3) < 3
+1 NULL 1
+create or replace view v1 as select 2 DIV 3 <> 3, 2 DIV (3 <> 3), (2 DIV 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 <> 3 AS `2 DIV 3 <> 3`,2 DIV (3 <> 3) AS `2 DIV (3 <> 3)`,2 DIV 3 <> 3 AS `(2 DIV 3) <> 3`
+select 2 DIV 3 <> 3, 2 DIV (3 <> 3), (2 DIV 3) <> 3 union select * from v1;
+2 DIV 3 <> 3 2 DIV (3 <> 3) (2 DIV 3) <> 3
+1 NULL 1
+create or replace view v1 as select 2 DIV 3 > 3, 2 DIV (3 > 3), (2 DIV 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 > 3 AS `2 DIV 3 > 3`,2 DIV (3 > 3) AS `2 DIV (3 > 3)`,2 DIV 3 > 3 AS `(2 DIV 3) > 3`
+select 2 DIV 3 > 3, 2 DIV (3 > 3), (2 DIV 3) > 3 union select * from v1;
+2 DIV 3 > 3 2 DIV (3 > 3) (2 DIV 3) > 3
+0 NULL 0
+create or replace view v1 as select 2 DIV 3 != 3, 2 DIV (3 != 3), (2 DIV 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 <> 3 AS `2 DIV 3 != 3`,2 DIV (3 <> 3) AS `2 DIV (3 != 3)`,2 DIV 3 <> 3 AS `(2 DIV 3) != 3`
+select 2 DIV 3 != 3, 2 DIV (3 != 3), (2 DIV 3) != 3 union select * from v1;
+2 DIV 3 != 3 2 DIV (3 != 3) (2 DIV 3) != 3
+1 NULL 1
+create or replace view v1 as select 2 DIV 3 LIKE 3, 2 DIV (3 LIKE 3), (2 DIV 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 like 3 AS `2 DIV 3 LIKE 3`,2 DIV (3 like 3) AS `2 DIV (3 LIKE 3)`,2 DIV 3 like 3 AS `(2 DIV 3) LIKE 3`
+select 2 DIV 3 LIKE 3, 2 DIV (3 LIKE 3), (2 DIV 3) LIKE 3 union select * from v1;
+2 DIV 3 LIKE 3 2 DIV (3 LIKE 3) (2 DIV 3) LIKE 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 REGEXP 3, 2 DIV (3 REGEXP 3), (2 DIV 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 regexp 3 AS `2 DIV 3 REGEXP 3`,2 DIV (3 regexp 3) AS `2 DIV (3 REGEXP 3)`,2 DIV 3 regexp 3 AS `(2 DIV 3) REGEXP 3`
+select 2 DIV 3 REGEXP 3, 2 DIV (3 REGEXP 3), (2 DIV 3) REGEXP 3 union select * from v1;
+2 DIV 3 REGEXP 3 2 DIV (3 REGEXP 3) (2 DIV 3) REGEXP 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 | 3, 2 DIV (3 | 3), (2 DIV 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 | 3 AS `2 DIV 3 | 3`,2 DIV (3 | 3) AS `2 DIV (3 | 3)`,2 DIV 3 | 3 AS `(2 DIV 3) | 3`
+select 2 DIV 3 | 3, 2 DIV (3 | 3), (2 DIV 3) | 3 union select * from v1;
+2 DIV 3 | 3 2 DIV (3 | 3) (2 DIV 3) | 3
+3 0 3
+create or replace view v1 as select 2 DIV 3 & 1, 2 DIV (3 & 1), (2 DIV 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 & 1 AS `2 DIV 3 & 1`,2 DIV (3 & 1) AS `2 DIV (3 & 1)`,2 DIV 3 & 1 AS `(2 DIV 3) & 1`
+select 2 DIV 3 & 1, 2 DIV (3 & 1), (2 DIV 3) & 1 union select * from v1;
+2 DIV 3 & 1 2 DIV (3 & 1) (2 DIV 3) & 1
+0 2 0
+create or replace view v1 as select 4 DIV 3 << 3, 4 DIV (3 << 3), (4 DIV 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 DIV 3 << 3 AS `4 DIV 3 << 3`,4 DIV (3 << 3) AS `4 DIV (3 << 3)`,4 DIV 3 << 3 AS `(4 DIV 3) << 3`
+select 4 DIV 3 << 3, 4 DIV (3 << 3), (4 DIV 3) << 3 union select * from v1;
+4 DIV 3 << 3 4 DIV (3 << 3) (4 DIV 3) << 3
+8 0 8
+create or replace view v1 as select 2 DIV 3 >> 3, 2 DIV (3 >> 3), (2 DIV 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 >> 3 AS `2 DIV 3 >> 3`,2 DIV (3 >> 3) AS `2 DIV (3 >> 3)`,2 DIV 3 >> 3 AS `(2 DIV 3) >> 3`
+select 2 DIV 3 >> 3, 2 DIV (3 >> 3), (2 DIV 3) >> 3 union select * from v1;
+2 DIV 3 >> 3 2 DIV (3 >> 3) (2 DIV 3) >> 3
+0 NULL 0
+create or replace view v1 as select 2 DIV '2000-01-01' +INTERVAL 1 DAY, 2 DIV ('2000-01-01' +INTERVAL 1 DAY), (2 DIV '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV '2000-01-01' + interval 1 day AS `2 DIV '2000-01-01' +INTERVAL 1 DAY`,2 DIV ('2000-01-01' + interval 1 day) AS `2 DIV ('2000-01-01' +INTERVAL 1 DAY)`,2 DIV '2000-01-01' + interval 1 day AS `(2 DIV '2000-01-01') +INTERVAL 1 DAY`
+select 2 DIV '2000-01-01' +INTERVAL 1 DAY, 2 DIV ('2000-01-01' +INTERVAL 1 DAY), (2 DIV '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 DIV '2000-01-01' +INTERVAL 1 DAY 2 DIV ('2000-01-01' +INTERVAL 1 DAY) (2 DIV '2000-01-01') +INTERVAL 1 DAY
+NULL 0 NULL
+create or replace view v1 as select 2 DIV 3 + 3, 2 DIV (3 + 3), (2 DIV 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 + 3 AS `2 DIV 3 + 3`,2 DIV (3 + 3) AS `2 DIV (3 + 3)`,2 DIV 3 + 3 AS `(2 DIV 3) + 3`
+select 2 DIV 3 + 3, 2 DIV (3 + 3), (2 DIV 3) + 3 union select * from v1;
+2 DIV 3 + 3 2 DIV (3 + 3) (2 DIV 3) + 3
+3 0 3
+create or replace view v1 as select 2 DIV 3 - 3, 2 DIV (3 - 3), (2 DIV 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 - 3 AS `2 DIV 3 - 3`,2 DIV (3 - 3) AS `2 DIV (3 - 3)`,2 DIV 3 - 3 AS `(2 DIV 3) - 3`
+select 2 DIV 3 - 3, 2 DIV (3 - 3), (2 DIV 3) - 3 union select * from v1;
+2 DIV 3 - 3 2 DIV (3 - 3) (2 DIV 3) - 3
+-3 NULL -3
+create or replace view v1 as select 4 DIV 3 * 3, 4 DIV (3 * 3), (4 DIV 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 4 DIV 3 * 3 AS `4 DIV 3 * 3`,4 DIV (3 * 3) AS `4 DIV (3 * 3)`,4 DIV 3 * 3 AS `(4 DIV 3) * 3`
+select 4 DIV 3 * 3, 4 DIV (3 * 3), (4 DIV 3) * 3 union select * from v1;
+4 DIV 3 * 3 4 DIV (3 * 3) (4 DIV 3) * 3
+3 0 3
+create or replace view v1 as select 2 DIV 3 / 3, 2 DIV (3 / 3), (2 DIV 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 / 3 AS `2 DIV 3 / 3`,2 DIV (3 / 3) AS `2 DIV (3 / 3)`,2 DIV 3 / 3 AS `(2 DIV 3) / 3`
+select 2 DIV 3 / 3, 2 DIV (3 / 3), (2 DIV 3) / 3 union select * from v1;
+2 DIV 3 / 3 2 DIV (3 / 3) (2 DIV 3) / 3
+0.0000 2 0.0000
+create or replace view v1 as select 2 DIV 3 DIV 3, 2 DIV (3 DIV 3), (2 DIV 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 DIV 3 AS `2 DIV 3 DIV 3`,2 DIV (3 DIV 3) AS `2 DIV (3 DIV 3)`,2 DIV 3 DIV 3 AS `(2 DIV 3) DIV 3`
+select 2 DIV 3 DIV 3, 2 DIV (3 DIV 3), (2 DIV 3) DIV 3 union select * from v1;
+2 DIV 3 DIV 3 2 DIV (3 DIV 3) (2 DIV 3) DIV 3
+0 2 0
+create or replace view v1 as select 2 DIV 3 MOD 3, 2 DIV (3 MOD 3), (2 DIV 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 MOD 3 AS `2 DIV 3 MOD 3`,2 DIV (3 MOD 3) AS `2 DIV (3 MOD 3)`,2 DIV 3 MOD 3 AS `(2 DIV 3) MOD 3`
+select 2 DIV 3 MOD 3, 2 DIV (3 MOD 3), (2 DIV 3) MOD 3 union select * from v1;
+2 DIV 3 MOD 3 2 DIV (3 MOD 3) (2 DIV 3) MOD 3
+0 NULL 0
+create or replace view v1 as select 2 DIV 3 % 3, 2 DIV (3 % 3), (2 DIV 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 MOD 3 AS `2 DIV 3 % 3`,2 DIV (3 MOD 3) AS `2 DIV (3 % 3)`,2 DIV 3 MOD 3 AS `(2 DIV 3) % 3`
+select 2 DIV 3 % 3, 2 DIV (3 % 3), (2 DIV 3) % 3 union select * from v1;
+2 DIV 3 % 3 2 DIV (3 % 3) (2 DIV 3) % 3
+0 NULL 0
+create or replace view v1 as select 2 DIV 3 ^ 3, 2 DIV (3 ^ 3), (2 DIV 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 ^ 3 AS `2 DIV 3 ^ 3`,2 DIV 3 ^ 3 AS `2 DIV (3 ^ 3)`,(2 DIV 3) ^ 3 AS `(2 DIV 3) ^ 3`
+select 2 DIV 3 ^ 3, 2 DIV (3 ^ 3), (2 DIV 3) ^ 3 union select * from v1;
+2 DIV 3 ^ 3 2 DIV (3 ^ 3) (2 DIV 3) ^ 3
+NULL NULL 3
+create or replace view v1 as select 2 DIV 3 BETWEEN 1 AND 3, 2 DIV (3 BETWEEN 1 AND 3), (2 DIV 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 between 1 and 3 AS `2 DIV 3 BETWEEN 1 AND 3`,2 DIV (3 between 1 and 3) AS `2 DIV (3 BETWEEN 1 AND 3)`,2 DIV 3 between 1 and 3 AS `(2 DIV 3) BETWEEN 1 AND 3`
+select 2 DIV 3 BETWEEN 1 AND 3, 2 DIV (3 BETWEEN 1 AND 3), (2 DIV 3) BETWEEN 1 AND 3 union select * from v1;
+2 DIV 3 BETWEEN 1 AND 3 2 DIV (3 BETWEEN 1 AND 3) (2 DIV 3) BETWEEN 1 AND 3
+0 2 0
+create or replace view v1 as select 2 MOD 3 IS FALSE, 2 MOD (3 IS FALSE), (2 MOD 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 is false AS `2 MOD 3 IS FALSE`,2 MOD (3 is false) AS `2 MOD (3 IS FALSE)`,2 MOD 3 is false AS `(2 MOD 3) IS FALSE`
+select 2 MOD 3 IS FALSE, 2 MOD (3 IS FALSE), (2 MOD 3) IS FALSE union select * from v1;
+2 MOD 3 IS FALSE 2 MOD (3 IS FALSE) (2 MOD 3) IS FALSE
+0 NULL 0
+create or replace view v1 as select charset(2 MOD 3 COLLATE latin1_bin), charset(2 MOD (3 COLLATE latin1_bin)), charset((2 MOD 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 MOD 3 collate latin1_bin) AS `charset(2 MOD 3 COLLATE latin1_bin)`,charset(2 MOD 3 collate latin1_bin) AS `charset(2 MOD (3 COLLATE latin1_bin))`,charset((2 MOD 3) collate latin1_bin) AS `charset((2 MOD 3) COLLATE latin1_bin)`
+select charset(2 MOD 3 COLLATE latin1_bin), charset(2 MOD (3 COLLATE latin1_bin)), charset((2 MOD 3) COLLATE latin1_bin) union select * from v1;
+charset(2 MOD 3 COLLATE latin1_bin) charset(2 MOD (3 COLLATE latin1_bin)) charset((2 MOD 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 MOD 3 IN (0,1), 2 MOD (3 IN (0,1)), (2 MOD 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 in (0,1) AS `2 MOD 3 IN (0,1)`,2 MOD (3 in (0,1)) AS `2 MOD (3 IN (0,1))`,2 MOD 3 in (0,1) AS `(2 MOD 3) IN (0,1)`
+select 2 MOD 3 IN (0,1), 2 MOD (3 IN (0,1)), (2 MOD 3) IN (0,1) union select * from v1;
+2 MOD 3 IN (0,1) 2 MOD (3 IN (0,1)) (2 MOD 3) IN (0,1)
+0 NULL 0
+create or replace view v1 as select 2 MOD 3 OR 3, 2 MOD (3 OR 3), (2 MOD 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 or 3 AS `2 MOD 3 OR 3`,2 MOD (3 or 3) AS `2 MOD (3 OR 3)`,2 MOD 3 or 3 AS `(2 MOD 3) OR 3`
+select 2 MOD 3 OR 3, 2 MOD (3 OR 3), (2 MOD 3) OR 3 union select * from v1;
+2 MOD 3 OR 3 2 MOD (3 OR 3) (2 MOD 3) OR 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 or 3 AS `2 MOD 3 || 3`,2 MOD (3 or 3) AS `2 MOD (3 || 3)`,2 MOD 3 or 3 AS `(2 MOD 3) || 3`
+select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3 union select * from v1;
+2 MOD 3 || 3 2 MOD (3 || 3) (2 MOD 3) || 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 XOR 3, 2 MOD (3 XOR 3), (2 MOD 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 xor 3 AS `2 MOD 3 XOR 3`,2 MOD (3 xor 3) AS `2 MOD (3 XOR 3)`,2 MOD 3 xor 3 AS `(2 MOD 3) XOR 3`
+select 2 MOD 3 XOR 3, 2 MOD (3 XOR 3), (2 MOD 3) XOR 3 union select * from v1;
+2 MOD 3 XOR 3 2 MOD (3 XOR 3) (2 MOD 3) XOR 3
+0 NULL 0
+create or replace view v1 as select 2 MOD 3 AND 3, 2 MOD (3 AND 3), (2 MOD 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 and 3 AS `2 MOD 3 AND 3`,2 MOD (3 and 3) AS `2 MOD (3 AND 3)`,2 MOD 3 and 3 AS `(2 MOD 3) AND 3`
+select 2 MOD 3 AND 3, 2 MOD (3 AND 3), (2 MOD 3) AND 3 union select * from v1;
+2 MOD 3 AND 3 2 MOD (3 AND 3) (2 MOD 3) AND 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 && 3, 2 MOD (3 && 3), (2 MOD 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 and 3 AS `2 MOD 3 && 3`,2 MOD (3 and 3) AS `2 MOD (3 && 3)`,2 MOD 3 and 3 AS `(2 MOD 3) && 3`
+select 2 MOD 3 && 3, 2 MOD (3 && 3), (2 MOD 3) && 3 union select * from v1;
+2 MOD 3 && 3 2 MOD (3 && 3) (2 MOD 3) && 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 = 2, 2 MOD (3 = 2), (2 MOD 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 = 2 AS `2 MOD 3 = 2`,2 MOD (3 = 2) AS `2 MOD (3 = 2)`,2 MOD 3 = 2 AS `(2 MOD 3) = 2`
+select 2 MOD 3 = 2, 2 MOD (3 = 2), (2 MOD 3) = 2 union select * from v1;
+2 MOD 3 = 2 2 MOD (3 = 2) (2 MOD 3) = 2
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 <=> 2, 2 MOD (3 <=> 2), (2 MOD 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <=> 2 AS `2 MOD 3 <=> 2`,2 MOD (3 <=> 2) AS `2 MOD (3 <=> 2)`,2 MOD 3 <=> 2 AS `(2 MOD 3) <=> 2`
+select 2 MOD 3 <=> 2, 2 MOD (3 <=> 2), (2 MOD 3) <=> 2 union select * from v1;
+2 MOD 3 <=> 2 2 MOD (3 <=> 2) (2 MOD 3) <=> 2
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 >= 1, 2 MOD (3 >= 1), (2 MOD 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 >= 1 AS `2 MOD 3 >= 1`,2 MOD (3 >= 1) AS `2 MOD (3 >= 1)`,2 MOD 3 >= 1 AS `(2 MOD 3) >= 1`
+select 2 MOD 3 >= 1, 2 MOD (3 >= 1), (2 MOD 3) >= 1 union select * from v1;
+2 MOD 3 >= 1 2 MOD (3 >= 1) (2 MOD 3) >= 1
+1 0 1
+create or replace view v1 as select 2 MOD 3 <= 3, 2 MOD (3 <= 3), (2 MOD 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <= 3 AS `2 MOD 3 <= 3`,2 MOD (3 <= 3) AS `2 MOD (3 <= 3)`,2 MOD 3 <= 3 AS `(2 MOD 3) <= 3`
+select 2 MOD 3 <= 3, 2 MOD (3 <= 3), (2 MOD 3) <= 3 union select * from v1;
+2 MOD 3 <= 3 2 MOD (3 <= 3) (2 MOD 3) <= 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 < 3, 2 MOD (3 < 3), (2 MOD 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 < 3 AS `2 MOD 3 < 3`,2 MOD (3 < 3) AS `2 MOD (3 < 3)`,2 MOD 3 < 3 AS `(2 MOD 3) < 3`
+select 2 MOD 3 < 3, 2 MOD (3 < 3), (2 MOD 3) < 3 union select * from v1;
+2 MOD 3 < 3 2 MOD (3 < 3) (2 MOD 3) < 3
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 <> 3, 2 MOD (3 <> 3), (2 MOD 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <> 3 AS `2 MOD 3 <> 3`,2 MOD (3 <> 3) AS `2 MOD (3 <> 3)`,2 MOD 3 <> 3 AS `(2 MOD 3) <> 3`
+select 2 MOD 3 <> 3, 2 MOD (3 <> 3), (2 MOD 3) <> 3 union select * from v1;
+2 MOD 3 <> 3 2 MOD (3 <> 3) (2 MOD 3) <> 3
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 > 3, 2 MOD (3 > 3), (2 MOD 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 > 3 AS `2 MOD 3 > 3`,2 MOD (3 > 3) AS `2 MOD (3 > 3)`,2 MOD 3 > 3 AS `(2 MOD 3) > 3`
+select 2 MOD 3 > 3, 2 MOD (3 > 3), (2 MOD 3) > 3 union select * from v1;
+2 MOD 3 > 3 2 MOD (3 > 3) (2 MOD 3) > 3
+0 NULL 0
+create or replace view v1 as select 2 MOD 3 != 3, 2 MOD (3 != 3), (2 MOD 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <> 3 AS `2 MOD 3 != 3`,2 MOD (3 <> 3) AS `2 MOD (3 != 3)`,2 MOD 3 <> 3 AS `(2 MOD 3) != 3`
+select 2 MOD 3 != 3, 2 MOD (3 != 3), (2 MOD 3) != 3 union select * from v1;
+2 MOD 3 != 3 2 MOD (3 != 3) (2 MOD 3) != 3
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 LIKE 2, 2 MOD (3 LIKE 2), (2 MOD 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 like 2 AS `2 MOD 3 LIKE 2`,2 MOD (3 like 2) AS `2 MOD (3 LIKE 2)`,2 MOD 3 like 2 AS `(2 MOD 3) LIKE 2`
+select 2 MOD 3 LIKE 2, 2 MOD (3 LIKE 2), (2 MOD 3) LIKE 2 union select * from v1;
+2 MOD 3 LIKE 2 2 MOD (3 LIKE 2) (2 MOD 3) LIKE 2
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 REGEXP 2, 2 MOD (3 REGEXP 2), (2 MOD 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 regexp 2 AS `2 MOD 3 REGEXP 2`,2 MOD (3 regexp 2) AS `2 MOD (3 REGEXP 2)`,2 MOD 3 regexp 2 AS `(2 MOD 3) REGEXP 2`
+select 2 MOD 3 REGEXP 2, 2 MOD (3 REGEXP 2), (2 MOD 3) REGEXP 2 union select * from v1;
+2 MOD 3 REGEXP 2 2 MOD (3 REGEXP 2) (2 MOD 3) REGEXP 2
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 | 3, 2 MOD (3 | 3), (2 MOD 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 | 3 AS `2 MOD 3 | 3`,2 MOD (3 | 3) AS `2 MOD (3 | 3)`,2 MOD 3 | 3 AS `(2 MOD 3) | 3`
+select 2 MOD 3 | 3, 2 MOD (3 | 3), (2 MOD 3) | 3 union select * from v1;
+2 MOD 3 | 3 2 MOD (3 | 3) (2 MOD 3) | 3
+3 2 3
+create or replace view v1 as select 2 MOD 4 & 4, 2 MOD (4 & 4), (2 MOD 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 4 & 4 AS `2 MOD 4 & 4`,2 MOD (4 & 4) AS `2 MOD (4 & 4)`,2 MOD 4 & 4 AS `(2 MOD 4) & 4`
+select 2 MOD 4 & 4, 2 MOD (4 & 4), (2 MOD 4) & 4 union select * from v1;
+2 MOD 4 & 4 2 MOD (4 & 4) (2 MOD 4) & 4
+0 2 0
+create or replace view v1 as select 2 MOD 3 << 3, 2 MOD (3 << 3), (2 MOD 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 << 3 AS `2 MOD 3 << 3`,2 MOD (3 << 3) AS `2 MOD (3 << 3)`,2 MOD 3 << 3 AS `(2 MOD 3) << 3`
+select 2 MOD 3 << 3, 2 MOD (3 << 3), (2 MOD 3) << 3 union select * from v1;
+2 MOD 3 << 3 2 MOD (3 << 3) (2 MOD 3) << 3
+16 2 16
+create or replace view v1 as select 2 MOD 3 >> 3, 2 MOD (3 >> 3), (2 MOD 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 >> 3 AS `2 MOD 3 >> 3`,2 MOD (3 >> 3) AS `2 MOD (3 >> 3)`,2 MOD 3 >> 3 AS `(2 MOD 3) >> 3`
+select 2 MOD 3 >> 3, 2 MOD (3 >> 3), (2 MOD 3) >> 3 union select * from v1;
+2 MOD 3 >> 3 2 MOD (3 >> 3) (2 MOD 3) >> 3
+0 NULL 0
+create or replace view v1 as select 2 MOD '2000-01-01' +INTERVAL 1 DAY, 2 MOD ('2000-01-01' +INTERVAL 1 DAY), (2 MOD '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD '2000-01-01' + interval 1 day AS `2 MOD '2000-01-01' +INTERVAL 1 DAY`,2 MOD ('2000-01-01' + interval 1 day) AS `2 MOD ('2000-01-01' +INTERVAL 1 DAY)`,2 MOD '2000-01-01' + interval 1 day AS `(2 MOD '2000-01-01') +INTERVAL 1 DAY`
+select 2 MOD '2000-01-01' +INTERVAL 1 DAY, 2 MOD ('2000-01-01' +INTERVAL 1 DAY), (2 MOD '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 MOD '2000-01-01' +INTERVAL 1 DAY 2 MOD ('2000-01-01' +INTERVAL 1 DAY) (2 MOD '2000-01-01') +INTERVAL 1 DAY
+NULL 2 NULL
+create or replace view v1 as select 2 MOD 3 + 3, 2 MOD (3 + 3), (2 MOD 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 + 3 AS `2 MOD 3 + 3`,2 MOD (3 + 3) AS `2 MOD (3 + 3)`,2 MOD 3 + 3 AS `(2 MOD 3) + 3`
+select 2 MOD 3 + 3, 2 MOD (3 + 3), (2 MOD 3) + 3 union select * from v1;
+2 MOD 3 + 3 2 MOD (3 + 3) (2 MOD 3) + 3
+5 2 5
+create or replace view v1 as select 2 MOD 3 - 3, 2 MOD (3 - 3), (2 MOD 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 - 3 AS `2 MOD 3 - 3`,2 MOD (3 - 3) AS `2 MOD (3 - 3)`,2 MOD 3 - 3 AS `(2 MOD 3) - 3`
+select 2 MOD 3 - 3, 2 MOD (3 - 3), (2 MOD 3) - 3 union select * from v1;
+2 MOD 3 - 3 2 MOD (3 - 3) (2 MOD 3) - 3
+-1 NULL -1
+create or replace view v1 as select 2 MOD 3 * 3, 2 MOD (3 * 3), (2 MOD 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 * 3 AS `2 MOD 3 * 3`,2 MOD (3 * 3) AS `2 MOD (3 * 3)`,2 MOD 3 * 3 AS `(2 MOD 3) * 3`
+select 2 MOD 3 * 3, 2 MOD (3 * 3), (2 MOD 3) * 3 union select * from v1;
+2 MOD 3 * 3 2 MOD (3 * 3) (2 MOD 3) * 3
+6 2 6
+create or replace view v1 as select 2 MOD 3 / 3, 2 MOD (3 / 3), (2 MOD 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 / 3 AS `2 MOD 3 / 3`,2 MOD (3 / 3) AS `2 MOD (3 / 3)`,2 MOD 3 / 3 AS `(2 MOD 3) / 3`
+select 2 MOD 3 / 3, 2 MOD (3 / 3), (2 MOD 3) / 3 union select * from v1;
+2 MOD 3 / 3 2 MOD (3 / 3) (2 MOD 3) / 3
+0.6667 0.0000 0.6667
+create or replace view v1 as select 3 MOD 4 DIV 3, 3 MOD (4 DIV 3), (3 MOD 4) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 MOD 4 DIV 3 AS `3 MOD 4 DIV 3`,3 MOD (4 DIV 3) AS `3 MOD (4 DIV 3)`,3 MOD 4 DIV 3 AS `(3 MOD 4) DIV 3`
+select 3 MOD 4 DIV 3, 3 MOD (4 DIV 3), (3 MOD 4) DIV 3 union select * from v1;
+3 MOD 4 DIV 3 3 MOD (4 DIV 3) (3 MOD 4) DIV 3
+1 0 1
+create or replace view v1 as select 2 MOD 3 MOD 3, 2 MOD (3 MOD 3), (2 MOD 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 MOD 3 AS `2 MOD 3 MOD 3`,2 MOD (3 MOD 3) AS `2 MOD (3 MOD 3)`,2 MOD 3 MOD 3 AS `(2 MOD 3) MOD 3`
+select 2 MOD 3 MOD 3, 2 MOD (3 MOD 3), (2 MOD 3) MOD 3 union select * from v1;
+2 MOD 3 MOD 3 2 MOD (3 MOD 3) (2 MOD 3) MOD 3
+2 NULL 2
+create or replace view v1 as select 2 MOD 3 % 3, 2 MOD (3 % 3), (2 MOD 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 MOD 3 AS `2 MOD 3 % 3`,2 MOD (3 MOD 3) AS `2 MOD (3 % 3)`,2 MOD 3 MOD 3 AS `(2 MOD 3) % 3`
+select 2 MOD 3 % 3, 2 MOD (3 % 3), (2 MOD 3) % 3 union select * from v1;
+2 MOD 3 % 3 2 MOD (3 % 3) (2 MOD 3) % 3
+2 NULL 2
+create or replace view v1 as select 2 MOD 3 ^ 3, 2 MOD (3 ^ 3), (2 MOD 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 ^ 3 AS `2 MOD 3 ^ 3`,2 MOD 3 ^ 3 AS `2 MOD (3 ^ 3)`,(2 MOD 3) ^ 3 AS `(2 MOD 3) ^ 3`
+select 2 MOD 3 ^ 3, 2 MOD (3 ^ 3), (2 MOD 3) ^ 3 union select * from v1;
+2 MOD 3 ^ 3 2 MOD (3 ^ 3) (2 MOD 3) ^ 3
+NULL NULL 1
+create or replace view v1 as select 2 MOD 3 BETWEEN 1 AND 3, 2 MOD (3 BETWEEN 1 AND 3), (2 MOD 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 between 1 and 3 AS `2 MOD 3 BETWEEN 1 AND 3`,2 MOD (3 between 1 and 3) AS `2 MOD (3 BETWEEN 1 AND 3)`,2 MOD 3 between 1 and 3 AS `(2 MOD 3) BETWEEN 1 AND 3`
+select 2 MOD 3 BETWEEN 1 AND 3, 2 MOD (3 BETWEEN 1 AND 3), (2 MOD 3) BETWEEN 1 AND 3 union select * from v1;
+2 MOD 3 BETWEEN 1 AND 3 2 MOD (3 BETWEEN 1 AND 3) (2 MOD 3) BETWEEN 1 AND 3
+1 0 1
+create or replace view v1 as select 2 % 3 IS FALSE, 2 % (3 IS FALSE), (2 % 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 is false AS `2 % 3 IS FALSE`,2 MOD (3 is false) AS `2 % (3 IS FALSE)`,2 MOD 3 is false AS `(2 % 3) IS FALSE`
+select 2 % 3 IS FALSE, 2 % (3 IS FALSE), (2 % 3) IS FALSE union select * from v1;
+2 % 3 IS FALSE 2 % (3 IS FALSE) (2 % 3) IS FALSE
+0 NULL 0
+create or replace view v1 as select charset(2 % 3 COLLATE latin1_bin), charset(2 % (3 COLLATE latin1_bin)), charset((2 % 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 MOD 3 collate latin1_bin) AS `charset(2 % 3 COLLATE latin1_bin)`,charset(2 MOD 3 collate latin1_bin) AS `charset(2 % (3 COLLATE latin1_bin))`,charset((2 MOD 3) collate latin1_bin) AS `charset((2 % 3) COLLATE latin1_bin)`
+select charset(2 % 3 COLLATE latin1_bin), charset(2 % (3 COLLATE latin1_bin)), charset((2 % 3) COLLATE latin1_bin) union select * from v1;
+charset(2 % 3 COLLATE latin1_bin) charset(2 % (3 COLLATE latin1_bin)) charset((2 % 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 % 3 IN (0,1), 2 % (3 IN (0,1)), (2 % 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 in (0,1) AS `2 % 3 IN (0,1)`,2 MOD (3 in (0,1)) AS `2 % (3 IN (0,1))`,2 MOD 3 in (0,1) AS `(2 % 3) IN (0,1)`
+select 2 % 3 IN (0,1), 2 % (3 IN (0,1)), (2 % 3) IN (0,1) union select * from v1;
+2 % 3 IN (0,1) 2 % (3 IN (0,1)) (2 % 3) IN (0,1)
+0 NULL 0
+create or replace view v1 as select 2 % 3 OR 3, 2 % (3 OR 3), (2 % 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 or 3 AS `2 % 3 OR 3`,2 MOD (3 or 3) AS `2 % (3 OR 3)`,2 MOD 3 or 3 AS `(2 % 3) OR 3`
+select 2 % 3 OR 3, 2 % (3 OR 3), (2 % 3) OR 3 union select * from v1;
+2 % 3 OR 3 2 % (3 OR 3) (2 % 3) OR 3
+1 0 1
+create or replace view v1 as select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 or 3 AS `2 % 3 || 3`,2 MOD (3 or 3) AS `2 % (3 || 3)`,2 MOD 3 or 3 AS `(2 % 3) || 3`
+select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3 union select * from v1;
+2 % 3 || 3 2 % (3 || 3) (2 % 3) || 3
+1 0 1
+create or replace view v1 as select 2 % 3 XOR 3, 2 % (3 XOR 3), (2 % 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 xor 3 AS `2 % 3 XOR 3`,2 MOD (3 xor 3) AS `2 % (3 XOR 3)`,2 MOD 3 xor 3 AS `(2 % 3) XOR 3`
+select 2 % 3 XOR 3, 2 % (3 XOR 3), (2 % 3) XOR 3 union select * from v1;
+2 % 3 XOR 3 2 % (3 XOR 3) (2 % 3) XOR 3
+0 NULL 0
+create or replace view v1 as select 2 % 3 AND 3, 2 % (3 AND 3), (2 % 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 and 3 AS `2 % 3 AND 3`,2 MOD (3 and 3) AS `2 % (3 AND 3)`,2 MOD 3 and 3 AS `(2 % 3) AND 3`
+select 2 % 3 AND 3, 2 % (3 AND 3), (2 % 3) AND 3 union select * from v1;
+2 % 3 AND 3 2 % (3 AND 3) (2 % 3) AND 3
+1 0 1
+create or replace view v1 as select 2 % 3 && 3, 2 % (3 && 3), (2 % 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 and 3 AS `2 % 3 && 3`,2 MOD (3 and 3) AS `2 % (3 && 3)`,2 MOD 3 and 3 AS `(2 % 3) && 3`
+select 2 % 3 && 3, 2 % (3 && 3), (2 % 3) && 3 union select * from v1;
+2 % 3 && 3 2 % (3 && 3) (2 % 3) && 3
+1 0 1
+create or replace view v1 as select 2 % 3 = 2, 2 % (3 = 2), (2 % 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 = 2 AS `2 % 3 = 2`,2 MOD (3 = 2) AS `2 % (3 = 2)`,2 MOD 3 = 2 AS `(2 % 3) = 2`
+select 2 % 3 = 2, 2 % (3 = 2), (2 % 3) = 2 union select * from v1;
+2 % 3 = 2 2 % (3 = 2) (2 % 3) = 2
+1 NULL 1
+create or replace view v1 as select 2 % 3 <=> 2, 2 % (3 <=> 2), (2 % 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <=> 2 AS `2 % 3 <=> 2`,2 MOD (3 <=> 2) AS `2 % (3 <=> 2)`,2 MOD 3 <=> 2 AS `(2 % 3) <=> 2`
+select 2 % 3 <=> 2, 2 % (3 <=> 2), (2 % 3) <=> 2 union select * from v1;
+2 % 3 <=> 2 2 % (3 <=> 2) (2 % 3) <=> 2
+1 NULL 1
+create or replace view v1 as select 2 % 3 >= 1, 2 % (3 >= 1), (2 % 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 >= 1 AS `2 % 3 >= 1`,2 MOD (3 >= 1) AS `2 % (3 >= 1)`,2 MOD 3 >= 1 AS `(2 % 3) >= 1`
+select 2 % 3 >= 1, 2 % (3 >= 1), (2 % 3) >= 1 union select * from v1;
+2 % 3 >= 1 2 % (3 >= 1) (2 % 3) >= 1
+1 0 1
+create or replace view v1 as select 2 % 3 <= 3, 2 % (3 <= 3), (2 % 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <= 3 AS `2 % 3 <= 3`,2 MOD (3 <= 3) AS `2 % (3 <= 3)`,2 MOD 3 <= 3 AS `(2 % 3) <= 3`
+select 2 % 3 <= 3, 2 % (3 <= 3), (2 % 3) <= 3 union select * from v1;
+2 % 3 <= 3 2 % (3 <= 3) (2 % 3) <= 3
+1 0 1
+create or replace view v1 as select 2 % 3 < 3, 2 % (3 < 3), (2 % 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 < 3 AS `2 % 3 < 3`,2 MOD (3 < 3) AS `2 % (3 < 3)`,2 MOD 3 < 3 AS `(2 % 3) < 3`
+select 2 % 3 < 3, 2 % (3 < 3), (2 % 3) < 3 union select * from v1;
+2 % 3 < 3 2 % (3 < 3) (2 % 3) < 3
+1 NULL 1
+create or replace view v1 as select 2 % 3 <> 3, 2 % (3 <> 3), (2 % 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <> 3 AS `2 % 3 <> 3`,2 MOD (3 <> 3) AS `2 % (3 <> 3)`,2 MOD 3 <> 3 AS `(2 % 3) <> 3`
+select 2 % 3 <> 3, 2 % (3 <> 3), (2 % 3) <> 3 union select * from v1;
+2 % 3 <> 3 2 % (3 <> 3) (2 % 3) <> 3
+1 NULL 1
+create or replace view v1 as select 2 % 3 > 3, 2 % (3 > 3), (2 % 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 > 3 AS `2 % 3 > 3`,2 MOD (3 > 3) AS `2 % (3 > 3)`,2 MOD 3 > 3 AS `(2 % 3) > 3`
+select 2 % 3 > 3, 2 % (3 > 3), (2 % 3) > 3 union select * from v1;
+2 % 3 > 3 2 % (3 > 3) (2 % 3) > 3
+0 NULL 0
+create or replace view v1 as select 2 % 3 != 3, 2 % (3 != 3), (2 % 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 <> 3 AS `2 % 3 != 3`,2 MOD (3 <> 3) AS `2 % (3 != 3)`,2 MOD 3 <> 3 AS `(2 % 3) != 3`
+select 2 % 3 != 3, 2 % (3 != 3), (2 % 3) != 3 union select * from v1;
+2 % 3 != 3 2 % (3 != 3) (2 % 3) != 3
+1 NULL 1
+create or replace view v1 as select 2 % 3 LIKE 2, 2 % (3 LIKE 2), (2 % 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 like 2 AS `2 % 3 LIKE 2`,2 MOD (3 like 2) AS `2 % (3 LIKE 2)`,2 MOD 3 like 2 AS `(2 % 3) LIKE 2`
+select 2 % 3 LIKE 2, 2 % (3 LIKE 2), (2 % 3) LIKE 2 union select * from v1;
+2 % 3 LIKE 2 2 % (3 LIKE 2) (2 % 3) LIKE 2
+1 NULL 1
+create or replace view v1 as select 2 % 3 REGEXP 2, 2 % (3 REGEXP 2), (2 % 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 regexp 2 AS `2 % 3 REGEXP 2`,2 MOD (3 regexp 2) AS `2 % (3 REGEXP 2)`,2 MOD 3 regexp 2 AS `(2 % 3) REGEXP 2`
+select 2 % 3 REGEXP 2, 2 % (3 REGEXP 2), (2 % 3) REGEXP 2 union select * from v1;
+2 % 3 REGEXP 2 2 % (3 REGEXP 2) (2 % 3) REGEXP 2
+1 NULL 1
+create or replace view v1 as select 2 % 3 | 3, 2 % (3 | 3), (2 % 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 | 3 AS `2 % 3 | 3`,2 MOD (3 | 3) AS `2 % (3 | 3)`,2 MOD 3 | 3 AS `(2 % 3) | 3`
+select 2 % 3 | 3, 2 % (3 | 3), (2 % 3) | 3 union select * from v1;
+2 % 3 | 3 2 % (3 | 3) (2 % 3) | 3
+3 2 3
+create or replace view v1 as select 2 % 4 & 4, 2 % (4 & 4), (2 % 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 4 & 4 AS `2 % 4 & 4`,2 MOD (4 & 4) AS `2 % (4 & 4)`,2 MOD 4 & 4 AS `(2 % 4) & 4`
+select 2 % 4 & 4, 2 % (4 & 4), (2 % 4) & 4 union select * from v1;
+2 % 4 & 4 2 % (4 & 4) (2 % 4) & 4
+0 2 0
+create or replace view v1 as select 2 % 3 << 3, 2 % (3 << 3), (2 % 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 << 3 AS `2 % 3 << 3`,2 MOD (3 << 3) AS `2 % (3 << 3)`,2 MOD 3 << 3 AS `(2 % 3) << 3`
+select 2 % 3 << 3, 2 % (3 << 3), (2 % 3) << 3 union select * from v1;
+2 % 3 << 3 2 % (3 << 3) (2 % 3) << 3
+16 2 16
+create or replace view v1 as select 2 % 3 >> 3, 2 % (3 >> 3), (2 % 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 >> 3 AS `2 % 3 >> 3`,2 MOD (3 >> 3) AS `2 % (3 >> 3)`,2 MOD 3 >> 3 AS `(2 % 3) >> 3`
+select 2 % 3 >> 3, 2 % (3 >> 3), (2 % 3) >> 3 union select * from v1;
+2 % 3 >> 3 2 % (3 >> 3) (2 % 3) >> 3
+0 NULL 0
+create or replace view v1 as select 2 % '2000-01-01' +INTERVAL 1 DAY, 2 % ('2000-01-01' +INTERVAL 1 DAY), (2 % '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD '2000-01-01' + interval 1 day AS `2 % '2000-01-01' +INTERVAL 1 DAY`,2 MOD ('2000-01-01' + interval 1 day) AS `2 % ('2000-01-01' +INTERVAL 1 DAY)`,2 MOD '2000-01-01' + interval 1 day AS `(2 % '2000-01-01') +INTERVAL 1 DAY`
+select 2 % '2000-01-01' +INTERVAL 1 DAY, 2 % ('2000-01-01' +INTERVAL 1 DAY), (2 % '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 % '2000-01-01' +INTERVAL 1 DAY 2 % ('2000-01-01' +INTERVAL 1 DAY) (2 % '2000-01-01') +INTERVAL 1 DAY
+NULL 2 NULL
+create or replace view v1 as select 2 % 3 + 3, 2 % (3 + 3), (2 % 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 + 3 AS `2 % 3 + 3`,2 MOD (3 + 3) AS `2 % (3 + 3)`,2 MOD 3 + 3 AS `(2 % 3) + 3`
+select 2 % 3 + 3, 2 % (3 + 3), (2 % 3) + 3 union select * from v1;
+2 % 3 + 3 2 % (3 + 3) (2 % 3) + 3
+5 2 5
+create or replace view v1 as select 2 % 3 - 3, 2 % (3 - 3), (2 % 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 - 3 AS `2 % 3 - 3`,2 MOD (3 - 3) AS `2 % (3 - 3)`,2 MOD 3 - 3 AS `(2 % 3) - 3`
+select 2 % 3 - 3, 2 % (3 - 3), (2 % 3) - 3 union select * from v1;
+2 % 3 - 3 2 % (3 - 3) (2 % 3) - 3
+-1 NULL -1
+create or replace view v1 as select 2 % 3 * 3, 2 % (3 * 3), (2 % 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 * 3 AS `2 % 3 * 3`,2 MOD (3 * 3) AS `2 % (3 * 3)`,2 MOD 3 * 3 AS `(2 % 3) * 3`
+select 2 % 3 * 3, 2 % (3 * 3), (2 % 3) * 3 union select * from v1;
+2 % 3 * 3 2 % (3 * 3) (2 % 3) * 3
+6 2 6
+create or replace view v1 as select 2 % 3 / 3, 2 % (3 / 3), (2 % 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 / 3 AS `2 % 3 / 3`,2 MOD (3 / 3) AS `2 % (3 / 3)`,2 MOD 3 / 3 AS `(2 % 3) / 3`
+select 2 % 3 / 3, 2 % (3 / 3), (2 % 3) / 3 union select * from v1;
+2 % 3 / 3 2 % (3 / 3) (2 % 3) / 3
+0.6667 0.0000 0.6667
+create or replace view v1 as select 3 % 4 DIV 3, 3 % (4 DIV 3), (3 % 4) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 MOD 4 DIV 3 AS `3 % 4 DIV 3`,3 MOD (4 DIV 3) AS `3 % (4 DIV 3)`,3 MOD 4 DIV 3 AS `(3 % 4) DIV 3`
+select 3 % 4 DIV 3, 3 % (4 DIV 3), (3 % 4) DIV 3 union select * from v1;
+3 % 4 DIV 3 3 % (4 DIV 3) (3 % 4) DIV 3
+1 0 1
+create or replace view v1 as select 2 % 3 MOD 3, 2 % (3 MOD 3), (2 % 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 MOD 3 AS `2 % 3 MOD 3`,2 MOD (3 MOD 3) AS `2 % (3 MOD 3)`,2 MOD 3 MOD 3 AS `(2 % 3) MOD 3`
+select 2 % 3 MOD 3, 2 % (3 MOD 3), (2 % 3) MOD 3 union select * from v1;
+2 % 3 MOD 3 2 % (3 MOD 3) (2 % 3) MOD 3
+2 NULL 2
+create or replace view v1 as select 2 % 3 % 3, 2 % (3 % 3), (2 % 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 MOD 3 AS `2 % 3 % 3`,2 MOD (3 MOD 3) AS `2 % (3 % 3)`,2 MOD 3 MOD 3 AS `(2 % 3) % 3`
+select 2 % 3 % 3, 2 % (3 % 3), (2 % 3) % 3 union select * from v1;
+2 % 3 % 3 2 % (3 % 3) (2 % 3) % 3
+2 NULL 2
+create or replace view v1 as select 2 % 3 ^ 3, 2 % (3 ^ 3), (2 % 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 ^ 3 AS `2 % 3 ^ 3`,2 MOD 3 ^ 3 AS `2 % (3 ^ 3)`,(2 MOD 3) ^ 3 AS `(2 % 3) ^ 3`
+select 2 % 3 ^ 3, 2 % (3 ^ 3), (2 % 3) ^ 3 union select * from v1;
+2 % 3 ^ 3 2 % (3 ^ 3) (2 % 3) ^ 3
+NULL NULL 1
+create or replace view v1 as select 2 % 3 BETWEEN 1 AND 3, 2 % (3 BETWEEN 1 AND 3), (2 % 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 between 1 and 3 AS `2 % 3 BETWEEN 1 AND 3`,2 MOD (3 between 1 and 3) AS `2 % (3 BETWEEN 1 AND 3)`,2 MOD 3 between 1 and 3 AS `(2 % 3) BETWEEN 1 AND 3`
+select 2 % 3 BETWEEN 1 AND 3, 2 % (3 BETWEEN 1 AND 3), (2 % 3) BETWEEN 1 AND 3 union select * from v1;
+2 % 3 BETWEEN 1 AND 3 2 % (3 BETWEEN 1 AND 3) (2 % 3) BETWEEN 1 AND 3
+1 0 1
+create or replace view v1 as select 2 ^ 3 IS FALSE, 2 ^ (3 IS FALSE), (2 ^ 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 is false AS `2 ^ 3 IS FALSE`,2 ^ (3 is false) AS `2 ^ (3 IS FALSE)`,2 ^ 3 is false AS `(2 ^ 3) IS FALSE`
+select 2 ^ 3 IS FALSE, 2 ^ (3 IS FALSE), (2 ^ 3) IS FALSE union select * from v1;
+2 ^ 3 IS FALSE 2 ^ (3 IS FALSE) (2 ^ 3) IS FALSE
+0 2 0
+create or replace view v1 as select charset(2 ^ 3 COLLATE latin1_bin), charset(2 ^ (3 COLLATE latin1_bin)), charset((2 ^ 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 ^ 3 collate latin1_bin) AS `charset(2 ^ 3 COLLATE latin1_bin)`,charset(2 ^ 3 collate latin1_bin) AS `charset(2 ^ (3 COLLATE latin1_bin))`,charset((2 ^ 3) collate latin1_bin) AS `charset((2 ^ 3) COLLATE latin1_bin)`
+select charset(2 ^ 3 COLLATE latin1_bin), charset(2 ^ (3 COLLATE latin1_bin)), charset((2 ^ 3) COLLATE latin1_bin) union select * from v1;
+charset(2 ^ 3 COLLATE latin1_bin) charset(2 ^ (3 COLLATE latin1_bin)) charset((2 ^ 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 ^ 3 IN (0,1), 2 ^ (3 IN (0,1)), (2 ^ 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 in (0,1) AS `2 ^ 3 IN (0,1)`,2 ^ (3 in (0,1)) AS `2 ^ (3 IN (0,1))`,2 ^ 3 in (0,1) AS `(2 ^ 3) IN (0,1)`
+select 2 ^ 3 IN (0,1), 2 ^ (3 IN (0,1)), (2 ^ 3) IN (0,1) union select * from v1;
+2 ^ 3 IN (0,1) 2 ^ (3 IN (0,1)) (2 ^ 3) IN (0,1)
+1 2 1
+create or replace view v1 as select 2 ^ 3 OR 3, 2 ^ (3 OR 3), (2 ^ 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 or 3 AS `2 ^ 3 OR 3`,2 ^ (3 or 3) AS `2 ^ (3 OR 3)`,2 ^ 3 or 3 AS `(2 ^ 3) OR 3`
+select 2 ^ 3 OR 3, 2 ^ (3 OR 3), (2 ^ 3) OR 3 union select * from v1;
+2 ^ 3 OR 3 2 ^ (3 OR 3) (2 ^ 3) OR 3
+1 3 1
+create or replace view v1 as select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 or 3 AS `2 ^ 3 || 3`,2 ^ (3 or 3) AS `2 ^ (3 || 3)`,2 ^ 3 or 3 AS `(2 ^ 3) || 3`
+select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3 union select * from v1;
+2 ^ 3 || 3 2 ^ (3 || 3) (2 ^ 3) || 3
+1 3 1
+create or replace view v1 as select 2 ^ 3 XOR 3, 2 ^ (3 XOR 3), (2 ^ 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 xor 3 AS `2 ^ 3 XOR 3`,2 ^ (3 xor 3) AS `2 ^ (3 XOR 3)`,2 ^ 3 xor 3 AS `(2 ^ 3) XOR 3`
+select 2 ^ 3 XOR 3, 2 ^ (3 XOR 3), (2 ^ 3) XOR 3 union select * from v1;
+2 ^ 3 XOR 3 2 ^ (3 XOR 3) (2 ^ 3) XOR 3
+0 2 0
+create or replace view v1 as select 2 ^ 3 AND 3, 2 ^ (3 AND 3), (2 ^ 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 and 3 AS `2 ^ 3 AND 3`,2 ^ (3 and 3) AS `2 ^ (3 AND 3)`,2 ^ 3 and 3 AS `(2 ^ 3) AND 3`
+select 2 ^ 3 AND 3, 2 ^ (3 AND 3), (2 ^ 3) AND 3 union select * from v1;
+2 ^ 3 AND 3 2 ^ (3 AND 3) (2 ^ 3) AND 3
+1 3 1
+create or replace view v1 as select 2 ^ 3 && 3, 2 ^ (3 && 3), (2 ^ 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 and 3 AS `2 ^ 3 && 3`,2 ^ (3 and 3) AS `2 ^ (3 && 3)`,2 ^ 3 and 3 AS `(2 ^ 3) && 3`
+select 2 ^ 3 && 3, 2 ^ (3 && 3), (2 ^ 3) && 3 union select * from v1;
+2 ^ 3 && 3 2 ^ (3 && 3) (2 ^ 3) && 3
+1 3 1
+create or replace view v1 as select 2 ^ 3 = 3, 2 ^ (3 = 3), (2 ^ 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 = 3 AS `2 ^ 3 = 3`,2 ^ (3 = 3) AS `2 ^ (3 = 3)`,2 ^ 3 = 3 AS `(2 ^ 3) = 3`
+select 2 ^ 3 = 3, 2 ^ (3 = 3), (2 ^ 3) = 3 union select * from v1;
+2 ^ 3 = 3 2 ^ (3 = 3) (2 ^ 3) = 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 <=> 3, 2 ^ (3 <=> 3), (2 ^ 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 <=> 3 AS `2 ^ 3 <=> 3`,2 ^ (3 <=> 3) AS `2 ^ (3 <=> 3)`,2 ^ 3 <=> 3 AS `(2 ^ 3) <=> 3`
+select 2 ^ 3 <=> 3, 2 ^ (3 <=> 3), (2 ^ 3) <=> 3 union select * from v1;
+2 ^ 3 <=> 3 2 ^ (3 <=> 3) (2 ^ 3) <=> 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 >= 3, 2 ^ (3 >= 3), (2 ^ 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 >= 3 AS `2 ^ 3 >= 3`,2 ^ (3 >= 3) AS `2 ^ (3 >= 3)`,2 ^ 3 >= 3 AS `(2 ^ 3) >= 3`
+select 2 ^ 3 >= 3, 2 ^ (3 >= 3), (2 ^ 3) >= 3 union select * from v1;
+2 ^ 3 >= 3 2 ^ (3 >= 3) (2 ^ 3) >= 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 <= 3, 2 ^ (3 <= 3), (2 ^ 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 <= 3 AS `2 ^ 3 <= 3`,2 ^ (3 <= 3) AS `2 ^ (3 <= 3)`,2 ^ 3 <= 3 AS `(2 ^ 3) <= 3`
+select 2 ^ 3 <= 3, 2 ^ (3 <= 3), (2 ^ 3) <= 3 union select * from v1;
+2 ^ 3 <= 3 2 ^ (3 <= 3) (2 ^ 3) <= 3
+1 3 1
+create or replace view v1 as select 2 ^ 3 < 3, 2 ^ (3 < 3), (2 ^ 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 < 3 AS `2 ^ 3 < 3`,2 ^ (3 < 3) AS `2 ^ (3 < 3)`,2 ^ 3 < 3 AS `(2 ^ 3) < 3`
+select 2 ^ 3 < 3, 2 ^ (3 < 3), (2 ^ 3) < 3 union select * from v1;
+2 ^ 3 < 3 2 ^ (3 < 3) (2 ^ 3) < 3
+1 2 1
+create or replace view v1 as select 2 ^ 3 <> 3, 2 ^ (3 <> 3), (2 ^ 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 <> 3 AS `2 ^ 3 <> 3`,2 ^ (3 <> 3) AS `2 ^ (3 <> 3)`,2 ^ 3 <> 3 AS `(2 ^ 3) <> 3`
+select 2 ^ 3 <> 3, 2 ^ (3 <> 3), (2 ^ 3) <> 3 union select * from v1;
+2 ^ 3 <> 3 2 ^ (3 <> 3) (2 ^ 3) <> 3
+1 2 1
+create or replace view v1 as select 2 ^ 3 > 3, 2 ^ (3 > 3), (2 ^ 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 > 3 AS `2 ^ 3 > 3`,2 ^ (3 > 3) AS `2 ^ (3 > 3)`,2 ^ 3 > 3 AS `(2 ^ 3) > 3`
+select 2 ^ 3 > 3, 2 ^ (3 > 3), (2 ^ 3) > 3 union select * from v1;
+2 ^ 3 > 3 2 ^ (3 > 3) (2 ^ 3) > 3
+0 2 0
+create or replace view v1 as select 2 ^ 3 != 3, 2 ^ (3 != 3), (2 ^ 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 <> 3 AS `2 ^ 3 != 3`,2 ^ (3 <> 3) AS `2 ^ (3 != 3)`,2 ^ 3 <> 3 AS `(2 ^ 3) != 3`
+select 2 ^ 3 != 3, 2 ^ (3 != 3), (2 ^ 3) != 3 union select * from v1;
+2 ^ 3 != 3 2 ^ (3 != 3) (2 ^ 3) != 3
+1 2 1
+create or replace view v1 as select 2 ^ 3 LIKE 3, 2 ^ (3 LIKE 3), (2 ^ 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 like 3 AS `2 ^ 3 LIKE 3`,2 ^ (3 like 3) AS `2 ^ (3 LIKE 3)`,2 ^ 3 like 3 AS `(2 ^ 3) LIKE 3`
+select 2 ^ 3 LIKE 3, 2 ^ (3 LIKE 3), (2 ^ 3) LIKE 3 union select * from v1;
+2 ^ 3 LIKE 3 2 ^ (3 LIKE 3) (2 ^ 3) LIKE 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 REGEXP 3, 2 ^ (3 REGEXP 3), (2 ^ 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 regexp 3 AS `2 ^ 3 REGEXP 3`,2 ^ (3 regexp 3) AS `2 ^ (3 REGEXP 3)`,2 ^ 3 regexp 3 AS `(2 ^ 3) REGEXP 3`
+select 2 ^ 3 REGEXP 3, 2 ^ (3 REGEXP 3), (2 ^ 3) REGEXP 3 union select * from v1;
+2 ^ 3 REGEXP 3 2 ^ (3 REGEXP 3) (2 ^ 3) REGEXP 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 | 3, 2 ^ (3 | 3), (2 ^ 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 | 3 AS `2 ^ 3 | 3`,2 ^ (3 | 3) AS `2 ^ (3 | 3)`,2 ^ 3 | 3 AS `(2 ^ 3) | 3`
+select 2 ^ 3 | 3, 2 ^ (3 | 3), (2 ^ 3) | 3 union select * from v1;
+2 ^ 3 | 3 2 ^ (3 | 3) (2 ^ 3) | 3
+3 1 3
+create or replace view v1 as select 2 ^ 0 & 0, 2 ^ (0 & 0), (2 ^ 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 0 & 0 AS `2 ^ 0 & 0`,2 ^ (0 & 0) AS `2 ^ (0 & 0)`,2 ^ 0 & 0 AS `(2 ^ 0) & 0`
+select 2 ^ 0 & 0, 2 ^ (0 & 0), (2 ^ 0) & 0 union select * from v1;
+2 ^ 0 & 0 2 ^ (0 & 0) (2 ^ 0) & 0
+0 2 0
+create or replace view v1 as select 2 ^ 3 << 3, 2 ^ (3 << 3), (2 ^ 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 << 3 AS `2 ^ 3 << 3`,2 ^ (3 << 3) AS `2 ^ (3 << 3)`,2 ^ 3 << 3 AS `(2 ^ 3) << 3`
+select 2 ^ 3 << 3, 2 ^ (3 << 3), (2 ^ 3) << 3 union select * from v1;
+2 ^ 3 << 3 2 ^ (3 << 3) (2 ^ 3) << 3
+8 26 8
+create or replace view v1 as select 2 ^ 3 >> 3, 2 ^ (3 >> 3), (2 ^ 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 >> 3 AS `2 ^ 3 >> 3`,2 ^ (3 >> 3) AS `2 ^ (3 >> 3)`,2 ^ 3 >> 3 AS `(2 ^ 3) >> 3`
+select 2 ^ 3 >> 3, 2 ^ (3 >> 3), (2 ^ 3) >> 3 union select * from v1;
+2 ^ 3 >> 3 2 ^ (3 >> 3) (2 ^ 3) >> 3
+0 2 0
+create or replace view v1 as select 2 ^ '2000-01-01' +INTERVAL 1 DAY, 2 ^ ('2000-01-01' +INTERVAL 1 DAY), (2 ^ '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ '2000-01-01' + interval 1 day AS `2 ^ '2000-01-01' +INTERVAL 1 DAY`,2 ^ ('2000-01-01' + interval 1 day) AS `2 ^ ('2000-01-01' +INTERVAL 1 DAY)`,2 ^ '2000-01-01' + interval 1 day AS `(2 ^ '2000-01-01') +INTERVAL 1 DAY`
+select 2 ^ '2000-01-01' +INTERVAL 1 DAY, 2 ^ ('2000-01-01' +INTERVAL 1 DAY), (2 ^ '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 ^ '2000-01-01' +INTERVAL 1 DAY 2 ^ ('2000-01-01' +INTERVAL 1 DAY) (2 ^ '2000-01-01') +INTERVAL 1 DAY
+NULL 20000100 NULL
+create or replace view v1 as select 2 ^ 3 + 1, 2 ^ (3 + 1), (2 ^ 3) + 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 + 1 AS `2 ^ 3 + 1`,2 ^ (3 + 1) AS `2 ^ (3 + 1)`,2 ^ 3 + 1 AS `(2 ^ 3) + 1`
+select 2 ^ 3 + 1, 2 ^ (3 + 1), (2 ^ 3) + 1 union select * from v1;
+2 ^ 3 + 1 2 ^ (3 + 1) (2 ^ 3) + 1
+2 6 2
+create or replace view v1 as select 5 ^ 1 - 1, 5 ^ (1 - 1), (5 ^ 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 5 ^ 1 - 1 AS `5 ^ 1 - 1`,5 ^ (1 - 1) AS `5 ^ (1 - 1)`,5 ^ 1 - 1 AS `(5 ^ 1) - 1`
+select 5 ^ 1 - 1, 5 ^ (1 - 1), (5 ^ 1) - 1 union select * from v1;
+5 ^ 1 - 1 5 ^ (1 - 1) (5 ^ 1) - 1
+3 5 3
+create or replace view v1 as select 2 ^ 3 * 3, 2 ^ (3 * 3), (2 ^ 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 * 3 AS `2 ^ 3 * 3`,2 ^ (3 * 3) AS `2 ^ (3 * 3)`,2 ^ 3 * 3 AS `(2 ^ 3) * 3`
+select 2 ^ 3 * 3, 2 ^ (3 * 3), (2 ^ 3) * 3 union select * from v1;
+2 ^ 3 * 3 2 ^ (3 * 3) (2 ^ 3) * 3
+3 11 3
+create or replace view v1 as select 2 ^ 3 / 3, 2 ^ (3 / 3), (2 ^ 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 / 3 AS `2 ^ 3 / 3`,2 ^ (3 / 3) AS `2 ^ (3 / 3)`,2 ^ 3 / 3 AS `(2 ^ 3) / 3`
+select 2 ^ 3 / 3, 2 ^ (3 / 3), (2 ^ 3) / 3 union select * from v1;
+2 ^ 3 / 3 2 ^ (3 / 3) (2 ^ 3) / 3
+0.3333 3 0.3333
+create or replace view v1 as select 2 ^ 3 DIV 3, 2 ^ (3 DIV 3), (2 ^ 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 DIV 3 AS `2 ^ 3 DIV 3`,2 ^ (3 DIV 3) AS `2 ^ (3 DIV 3)`,2 ^ 3 DIV 3 AS `(2 ^ 3) DIV 3`
+select 2 ^ 3 DIV 3, 2 ^ (3 DIV 3), (2 ^ 3) DIV 3 union select * from v1;
+2 ^ 3 DIV 3 2 ^ (3 DIV 3) (2 ^ 3) DIV 3
+0 3 0
+create or replace view v1 as select 2 ^ 3 MOD 3, 2 ^ (3 MOD 3), (2 ^ 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 MOD 3 AS `2 ^ 3 MOD 3`,2 ^ (3 MOD 3) AS `2 ^ (3 MOD 3)`,2 ^ 3 MOD 3 AS `(2 ^ 3) MOD 3`
+select 2 ^ 3 MOD 3, 2 ^ (3 MOD 3), (2 ^ 3) MOD 3 union select * from v1;
+2 ^ 3 MOD 3 2 ^ (3 MOD 3) (2 ^ 3) MOD 3
+1 2 1
+create or replace view v1 as select 2 ^ 3 % 3, 2 ^ (3 % 3), (2 ^ 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 MOD 3 AS `2 ^ 3 % 3`,2 ^ (3 MOD 3) AS `2 ^ (3 % 3)`,2 ^ 3 MOD 3 AS `(2 ^ 3) % 3`
+select 2 ^ 3 % 3, 2 ^ (3 % 3), (2 ^ 3) % 3 union select * from v1;
+2 ^ 3 % 3 2 ^ (3 % 3) (2 ^ 3) % 3
+1 2 1
+create or replace view v1 as select 2 ^ 3 BETWEEN 1 AND 3, 2 ^ (3 BETWEEN 1 AND 3), (2 ^ 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 between 1 and 3 AS `2 ^ 3 BETWEEN 1 AND 3`,2 ^ (3 between 1 and 3) AS `2 ^ (3 BETWEEN 1 AND 3)`,2 ^ 3 between 1 and 3 AS `(2 ^ 3) BETWEEN 1 AND 3`
+select 2 ^ 3 BETWEEN 1 AND 3, 2 ^ (3 BETWEEN 1 AND 3), (2 ^ 3) BETWEEN 1 AND 3 union select * from v1;
+2 ^ 3 BETWEEN 1 AND 3 2 ^ (3 BETWEEN 1 AND 3) (2 ^ 3) BETWEEN 1 AND 3
+1 3 1
+create or replace view v1 as select 2 BETWEEN 1 AND 1 IS FALSE, 2 BETWEEN 1 AND (1 IS FALSE), (2 BETWEEN 1 AND 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 1 is false AS `2 BETWEEN 1 AND 1 IS FALSE`,2 between 1 and (1 is false) AS `2 BETWEEN 1 AND (1 IS FALSE)`,2 between 1 and 1 is false AS `(2 BETWEEN 1 AND 1) IS FALSE`
+select 2 BETWEEN 1 AND 1 IS FALSE, 2 BETWEEN 1 AND (1 IS FALSE), (2 BETWEEN 1 AND 1) IS FALSE union select * from v1;
+2 BETWEEN 1 AND 1 IS FALSE 2 BETWEEN 1 AND (1 IS FALSE) (2 BETWEEN 1 AND 1) IS FALSE
+1 0 1
+create or replace view v1 as select charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin), charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin)), charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 between 1 and 3 collate latin1_bin) AS `charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin)`,charset(2 between 1 and 3 collate latin1_bin) AS `charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin))`,charset((2 between 1 and 3) collate latin1_bin) AS `charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin)`
+select charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin), charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin)), charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin) union select * from v1;
+charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin) charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin)) charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 IN (0,1), 2 BETWEEN 1 AND (3 IN (0,1)), (2 BETWEEN 1 AND 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 in (0,1) AS `2 BETWEEN 1 AND 3 IN (0,1)`,2 between 1 and 3 in (0,1) AS `2 BETWEEN 1 AND (3 IN (0,1))`,(2 between 1 and 3) in (0,1) AS `(2 BETWEEN 1 AND 3) IN (0,1)`
+select 2 BETWEEN 1 AND 3 IN (0,1), 2 BETWEEN 1 AND (3 IN (0,1)), (2 BETWEEN 1 AND 3) IN (0,1) union select * from v1;
+2 BETWEEN 1 AND 3 IN (0,1) 2 BETWEEN 1 AND (3 IN (0,1)) (2 BETWEEN 1 AND 3) IN (0,1)
+0 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 OR 3, 2 BETWEEN 1 AND (3 OR 3), (2 BETWEEN 1 AND 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 or 3 AS `2 BETWEEN 1 AND 3 OR 3`,2 between 1 and (3 or 3) AS `2 BETWEEN 1 AND (3 OR 3)`,2 between 1 and 3 or 3 AS `(2 BETWEEN 1 AND 3) OR 3`
+select 2 BETWEEN 1 AND 3 OR 3, 2 BETWEEN 1 AND (3 OR 3), (2 BETWEEN 1 AND 3) OR 3 union select * from v1;
+2 BETWEEN 1 AND 3 OR 3 2 BETWEEN 1 AND (3 OR 3) (2 BETWEEN 1 AND 3) OR 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 or 3 AS `2 BETWEEN 1 AND 3 || 3`,2 between 1 and (3 or 3) AS `2 BETWEEN 1 AND (3 || 3)`,2 between 1 and 3 or 3 AS `(2 BETWEEN 1 AND 3) || 3`
+select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3 union select * from v1;
+2 BETWEEN 1 AND 3 || 3 2 BETWEEN 1 AND (3 || 3) (2 BETWEEN 1 AND 3) || 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 1 XOR 1, 2 BETWEEN 1 AND (1 XOR 1), (2 BETWEEN 1 AND 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 1 xor 1 AS `2 BETWEEN 1 AND 1 XOR 1`,2 between 1 and (1 xor 1) AS `2 BETWEEN 1 AND (1 XOR 1)`,2 between 1 and 1 xor 1 AS `(2 BETWEEN 1 AND 1) XOR 1`
+select 2 BETWEEN 1 AND 1 XOR 1, 2 BETWEEN 1 AND (1 XOR 1), (2 BETWEEN 1 AND 1) XOR 1 union select * from v1;
+2 BETWEEN 1 AND 1 XOR 1 2 BETWEEN 1 AND (1 XOR 1) (2 BETWEEN 1 AND 1) XOR 1
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 AND 3, 2 BETWEEN 1 AND (3 AND 3), (2 BETWEEN 1 AND 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 and 3 AS `2 BETWEEN 1 AND 3 AND 3`,2 between 1 and (3 and 3) AS `2 BETWEEN 1 AND (3 AND 3)`,2 between 1 and 3 and 3 AS `(2 BETWEEN 1 AND 3) AND 3`
+select 2 BETWEEN 1 AND 3 AND 3, 2 BETWEEN 1 AND (3 AND 3), (2 BETWEEN 1 AND 3) AND 3 union select * from v1;
+2 BETWEEN 1 AND 3 AND 3 2 BETWEEN 1 AND (3 AND 3) (2 BETWEEN 1 AND 3) AND 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 && 3, 2 BETWEEN 1 AND (3 && 3), (2 BETWEEN 1 AND 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 and 3 AS `2 BETWEEN 1 AND 3 && 3`,2 between 1 and (3 and 3) AS `2 BETWEEN 1 AND (3 && 3)`,2 between 1 and 3 and 3 AS `(2 BETWEEN 1 AND 3) && 3`
+select 2 BETWEEN 1 AND 3 && 3, 2 BETWEEN 1 AND (3 && 3), (2 BETWEEN 1 AND 3) && 3 union select * from v1;
+2 BETWEEN 1 AND 3 && 3 2 BETWEEN 1 AND (3 && 3) (2 BETWEEN 1 AND 3) && 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 = 1, 2 BETWEEN 1 AND (3 = 1), (2 BETWEEN 1 AND 3) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 = 1 AS `2 BETWEEN 1 AND 3 = 1`,2 between 1 and (3 = 1) AS `2 BETWEEN 1 AND (3 = 1)`,2 between 1 and 3 = 1 AS `(2 BETWEEN 1 AND 3) = 1`
+select 2 BETWEEN 1 AND 3 = 1, 2 BETWEEN 1 AND (3 = 1), (2 BETWEEN 1 AND 3) = 1 union select * from v1;
+2 BETWEEN 1 AND 3 = 1 2 BETWEEN 1 AND (3 = 1) (2 BETWEEN 1 AND 3) = 1
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <=> 1, 2 BETWEEN 1 AND (3 <=> 1), (2 BETWEEN 1 AND 3) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 <=> 1 AS `2 BETWEEN 1 AND 3 <=> 1`,2 between 1 and (3 <=> 1) AS `2 BETWEEN 1 AND (3 <=> 1)`,2 between 1 and 3 <=> 1 AS `(2 BETWEEN 1 AND 3) <=> 1`
+select 2 BETWEEN 1 AND 3 <=> 1, 2 BETWEEN 1 AND (3 <=> 1), (2 BETWEEN 1 AND 3) <=> 1 union select * from v1;
+2 BETWEEN 1 AND 3 <=> 1 2 BETWEEN 1 AND (3 <=> 1) (2 BETWEEN 1 AND 3) <=> 1
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 >= 1, 2 BETWEEN 1 AND (3 >= 1), (2 BETWEEN 1 AND 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 >= 1 AS `2 BETWEEN 1 AND 3 >= 1`,2 between 1 and (3 >= 1) AS `2 BETWEEN 1 AND (3 >= 1)`,2 between 1 and 3 >= 1 AS `(2 BETWEEN 1 AND 3) >= 1`
+select 2 BETWEEN 1 AND 3 >= 1, 2 BETWEEN 1 AND (3 >= 1), (2 BETWEEN 1 AND 3) >= 1 union select * from v1;
+2 BETWEEN 1 AND 3 >= 1 2 BETWEEN 1 AND (3 >= 1) (2 BETWEEN 1 AND 3) >= 1
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <= 3, 2 BETWEEN 1 AND (3 <= 3), (2 BETWEEN 1 AND 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 <= 3 AS `2 BETWEEN 1 AND 3 <= 3`,2 between 1 and (3 <= 3) AS `2 BETWEEN 1 AND (3 <= 3)`,2 between 1 and 3 <= 3 AS `(2 BETWEEN 1 AND 3) <= 3`
+select 2 BETWEEN 1 AND 3 <= 3, 2 BETWEEN 1 AND (3 <= 3), (2 BETWEEN 1 AND 3) <= 3 union select * from v1;
+2 BETWEEN 1 AND 3 <= 3 2 BETWEEN 1 AND (3 <= 3) (2 BETWEEN 1 AND 3) <= 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 < 3, 2 BETWEEN 1 AND (3 < 3), (2 BETWEEN 1 AND 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 < 3 AS `2 BETWEEN 1 AND 3 < 3`,2 between 1 and (3 < 3) AS `2 BETWEEN 1 AND (3 < 3)`,2 between 1 and 3 < 3 AS `(2 BETWEEN 1 AND 3) < 3`
+select 2 BETWEEN 1 AND 3 < 3, 2 BETWEEN 1 AND (3 < 3), (2 BETWEEN 1 AND 3) < 3 union select * from v1;
+2 BETWEEN 1 AND 3 < 3 2 BETWEEN 1 AND (3 < 3) (2 BETWEEN 1 AND 3) < 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <> 3, 2 BETWEEN 1 AND (3 <> 3), (2 BETWEEN 1 AND 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 <> 3 AS `2 BETWEEN 1 AND 3 <> 3`,2 between 1 and (3 <> 3) AS `2 BETWEEN 1 AND (3 <> 3)`,2 between 1 and 3 <> 3 AS `(2 BETWEEN 1 AND 3) <> 3`
+select 2 BETWEEN 1 AND 3 <> 3, 2 BETWEEN 1 AND (3 <> 3), (2 BETWEEN 1 AND 3) <> 3 union select * from v1;
+2 BETWEEN 1 AND 3 <> 3 2 BETWEEN 1 AND (3 <> 3) (2 BETWEEN 1 AND 3) <> 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 > 0, 2 BETWEEN 1 AND (3 > 0), (2 BETWEEN 1 AND 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 > 0 AS `2 BETWEEN 1 AND 3 > 0`,2 between 1 and (3 > 0) AS `2 BETWEEN 1 AND (3 > 0)`,2 between 1 and 3 > 0 AS `(2 BETWEEN 1 AND 3) > 0`
+select 2 BETWEEN 1 AND 3 > 0, 2 BETWEEN 1 AND (3 > 0), (2 BETWEEN 1 AND 3) > 0 union select * from v1;
+2 BETWEEN 1 AND 3 > 0 2 BETWEEN 1 AND (3 > 0) (2 BETWEEN 1 AND 3) > 0
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 != 3, 2 BETWEEN 1 AND (3 != 3), (2 BETWEEN 1 AND 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 <> 3 AS `2 BETWEEN 1 AND 3 != 3`,2 between 1 and (3 <> 3) AS `2 BETWEEN 1 AND (3 != 3)`,2 between 1 and 3 <> 3 AS `(2 BETWEEN 1 AND 3) != 3`
+select 2 BETWEEN 1 AND 3 != 3, 2 BETWEEN 1 AND (3 != 3), (2 BETWEEN 1 AND 3) != 3 union select * from v1;
+2 BETWEEN 1 AND 3 != 3 2 BETWEEN 1 AND (3 != 3) (2 BETWEEN 1 AND 3) != 3
+1 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 LIKE 1, 2 BETWEEN 1 AND (3 LIKE 1), (2 BETWEEN 1 AND 3) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 like 1 AS `2 BETWEEN 1 AND 3 LIKE 1`,2 between 1 and 3 like 1 AS `2 BETWEEN 1 AND (3 LIKE 1)`,(2 between 1 and 3) like 1 AS `(2 BETWEEN 1 AND 3) LIKE 1`
+select 2 BETWEEN 1 AND 3 LIKE 1, 2 BETWEEN 1 AND (3 LIKE 1), (2 BETWEEN 1 AND 3) LIKE 1 union select * from v1;
+2 BETWEEN 1 AND 3 LIKE 1 2 BETWEEN 1 AND (3 LIKE 1) (2 BETWEEN 1 AND 3) LIKE 1
+0 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 REGEXP 1, 2 BETWEEN 1 AND (3 REGEXP 1), (2 BETWEEN 1 AND 3) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 regexp 1 AS `2 BETWEEN 1 AND 3 REGEXP 1`,2 between 1 and 3 regexp 1 AS `2 BETWEEN 1 AND (3 REGEXP 1)`,(2 between 1 and 3) regexp 1 AS `(2 BETWEEN 1 AND 3) REGEXP 1`
+select 2 BETWEEN 1 AND 3 REGEXP 1, 2 BETWEEN 1 AND (3 REGEXP 1), (2 BETWEEN 1 AND 3) REGEXP 1 union select * from v1;
+2 BETWEEN 1 AND 3 REGEXP 1 2 BETWEEN 1 AND (3 REGEXP 1) (2 BETWEEN 1 AND 3) REGEXP 1
+0 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 | 3, 2 BETWEEN 1 AND (3 | 3), (2 BETWEEN 1 AND 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 | 3 AS `2 BETWEEN 1 AND 3 | 3`,2 between 1 and 3 | 3 AS `2 BETWEEN 1 AND (3 | 3)`,(2 between 1 and 3) | 3 AS `(2 BETWEEN 1 AND 3) | 3`
+select 2 BETWEEN 1 AND 3 | 3, 2 BETWEEN 1 AND (3 | 3), (2 BETWEEN 1 AND 3) | 3 union select * from v1;
+2 BETWEEN 1 AND 3 | 3 2 BETWEEN 1 AND (3 | 3) (2 BETWEEN 1 AND 3) | 3
+1 1 3
+create or replace view v1 as select 2 BETWEEN 1 AND 2 & 2, 2 BETWEEN 1 AND (2 & 2), (2 BETWEEN 1 AND 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 2 & 2 AS `2 BETWEEN 1 AND 2 & 2`,2 between 1 and 2 & 2 AS `2 BETWEEN 1 AND (2 & 2)`,(2 between 1 and 2) & 2 AS `(2 BETWEEN 1 AND 2) & 2`
+select 2 BETWEEN 1 AND 2 & 2, 2 BETWEEN 1 AND (2 & 2), (2 BETWEEN 1 AND 2) & 2 union select * from v1;
+2 BETWEEN 1 AND 2 & 2 2 BETWEEN 1 AND (2 & 2) (2 BETWEEN 1 AND 2) & 2
+1 1 0
+create or replace view v1 as select 2 BETWEEN 1 AND 3 << 3, 2 BETWEEN 1 AND (3 << 3), (2 BETWEEN 1 AND 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 << 3 AS `2 BETWEEN 1 AND 3 << 3`,2 between 1 and 3 << 3 AS `2 BETWEEN 1 AND (3 << 3)`,(2 between 1 and 3) << 3 AS `(2 BETWEEN 1 AND 3) << 3`
+select 2 BETWEEN 1 AND 3 << 3, 2 BETWEEN 1 AND (3 << 3), (2 BETWEEN 1 AND 3) << 3 union select * from v1;
+2 BETWEEN 1 AND 3 << 3 2 BETWEEN 1 AND (3 << 3) (2 BETWEEN 1 AND 3) << 3
+1 1 8
+create or replace view v1 as select 2 BETWEEN 1 AND 4 >> 1, 2 BETWEEN 1 AND (4 >> 1), (2 BETWEEN 1 AND 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 4 >> 1 AS `2 BETWEEN 1 AND 4 >> 1`,2 between 1 and 4 >> 1 AS `2 BETWEEN 1 AND (4 >> 1)`,(2 between 1 and 4) >> 1 AS `(2 BETWEEN 1 AND 4) >> 1`
+select 2 BETWEEN 1 AND 4 >> 1, 2 BETWEEN 1 AND (4 >> 1), (2 BETWEEN 1 AND 4) >> 1 union select * from v1;
+2 BETWEEN 1 AND 4 >> 1 2 BETWEEN 1 AND (4 >> 1) (2 BETWEEN 1 AND 4) >> 1
+1 1 0
+create or replace view v1 as select 2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY, 2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY), (2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and '2000-01-01' + interval 1 day AS `2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY`,2 between 1 and '2000-01-01' + interval 1 day AS `2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY)`,(2 between 1 and '2000-01-01') + interval 1 day AS `(2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY`
+select 2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY, 2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY), (2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY 2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY) (2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY
+1 1 NULL
+create or replace view v1 as select 2 BETWEEN 1 AND 3 + 3, 2 BETWEEN 1 AND (3 + 3), (2 BETWEEN 1 AND 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 + 3 AS `2 BETWEEN 1 AND 3 + 3`,2 between 1 and 3 + 3 AS `2 BETWEEN 1 AND (3 + 3)`,(2 between 1 and 3) + 3 AS `(2 BETWEEN 1 AND 3) + 3`
+select 2 BETWEEN 1 AND 3 + 3, 2 BETWEEN 1 AND (3 + 3), (2 BETWEEN 1 AND 3) + 3 union select * from v1;
+2 BETWEEN 1 AND 3 + 3 2 BETWEEN 1 AND (3 + 3) (2 BETWEEN 1 AND 3) + 3
+1 1 4
+create or replace view v1 as select 2 BETWEEN 1 AND 3 - 3, 2 BETWEEN 1 AND (3 - 3), (2 BETWEEN 1 AND 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 - 3 AS `2 BETWEEN 1 AND 3 - 3`,2 between 1 and 3 - 3 AS `2 BETWEEN 1 AND (3 - 3)`,(2 between 1 and 3) - 3 AS `(2 BETWEEN 1 AND 3) - 3`
+select 2 BETWEEN 1 AND 3 - 3, 2 BETWEEN 1 AND (3 - 3), (2 BETWEEN 1 AND 3) - 3 union select * from v1;
+2 BETWEEN 1 AND 3 - 3 2 BETWEEN 1 AND (3 - 3) (2 BETWEEN 1 AND 3) - 3
+0 0 -2
+create or replace view v1 as select 2 BETWEEN 1 AND 3 * 3, 2 BETWEEN 1 AND (3 * 3), (2 BETWEEN 1 AND 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 * 3 AS `2 BETWEEN 1 AND 3 * 3`,2 between 1 and 3 * 3 AS `2 BETWEEN 1 AND (3 * 3)`,(2 between 1 and 3) * 3 AS `(2 BETWEEN 1 AND 3) * 3`
+select 2 BETWEEN 1 AND 3 * 3, 2 BETWEEN 1 AND (3 * 3), (2 BETWEEN 1 AND 3) * 3 union select * from v1;
+2 BETWEEN 1 AND 3 * 3 2 BETWEEN 1 AND (3 * 3) (2 BETWEEN 1 AND 3) * 3
+1 1 3
+create or replace view v1 as select 2 BETWEEN 1 AND 3 / 3, 2 BETWEEN 1 AND (3 / 3), (2 BETWEEN 1 AND 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 / 3 AS `2 BETWEEN 1 AND 3 / 3`,2 between 1 and 3 / 3 AS `2 BETWEEN 1 AND (3 / 3)`,(2 between 1 and 3) / 3 AS `(2 BETWEEN 1 AND 3) / 3`
+select 2 BETWEEN 1 AND 3 / 3, 2 BETWEEN 1 AND (3 / 3), (2 BETWEEN 1 AND 3) / 3 union select * from v1;
+2 BETWEEN 1 AND 3 / 3 2 BETWEEN 1 AND (3 / 3) (2 BETWEEN 1 AND 3) / 3
+0 0 0.3333
+create or replace view v1 as select 2 BETWEEN 1 AND 4 DIV 2, 2 BETWEEN 1 AND (4 DIV 2), (2 BETWEEN 1 AND 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 4 DIV 2 AS `2 BETWEEN 1 AND 4 DIV 2`,2 between 1 and 4 DIV 2 AS `2 BETWEEN 1 AND (4 DIV 2)`,(2 between 1 and 4) DIV 2 AS `(2 BETWEEN 1 AND 4) DIV 2`
+select 2 BETWEEN 1 AND 4 DIV 2, 2 BETWEEN 1 AND (4 DIV 2), (2 BETWEEN 1 AND 4) DIV 2 union select * from v1;
+2 BETWEEN 1 AND 4 DIV 2 2 BETWEEN 1 AND (4 DIV 2) (2 BETWEEN 1 AND 4) DIV 2
+1 1 0
+create or replace view v1 as select 2 BETWEEN 1 AND 3 MOD 3, 2 BETWEEN 1 AND (3 MOD 3), (2 BETWEEN 1 AND 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 MOD 3 AS `2 BETWEEN 1 AND 3 MOD 3`,2 between 1 and 3 MOD 3 AS `2 BETWEEN 1 AND (3 MOD 3)`,(2 between 1 and 3) MOD 3 AS `(2 BETWEEN 1 AND 3) MOD 3`
+select 2 BETWEEN 1 AND 3 MOD 3, 2 BETWEEN 1 AND (3 MOD 3), (2 BETWEEN 1 AND 3) MOD 3 union select * from v1;
+2 BETWEEN 1 AND 3 MOD 3 2 BETWEEN 1 AND (3 MOD 3) (2 BETWEEN 1 AND 3) MOD 3
+0 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 % 3, 2 BETWEEN 1 AND (3 % 3), (2 BETWEEN 1 AND 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 MOD 3 AS `2 BETWEEN 1 AND 3 % 3`,2 between 1 and 3 MOD 3 AS `2 BETWEEN 1 AND (3 % 3)`,(2 between 1 and 3) MOD 3 AS `(2 BETWEEN 1 AND 3) % 3`
+select 2 BETWEEN 1 AND 3 % 3, 2 BETWEEN 1 AND (3 % 3), (2 BETWEEN 1 AND 3) % 3 union select * from v1;
+2 BETWEEN 1 AND 3 % 3 2 BETWEEN 1 AND (3 % 3) (2 BETWEEN 1 AND 3) % 3
+0 0 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 ^ 3, 2 BETWEEN 1 AND (3 ^ 3), (2 BETWEEN 1 AND 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 ^ 3 AS `2 BETWEEN 1 AND 3 ^ 3`,2 between 1 and 3 ^ 3 AS `2 BETWEEN 1 AND (3 ^ 3)`,(2 between 1 and 3) ^ 3 AS `(2 BETWEEN 1 AND 3) ^ 3`
+select 2 BETWEEN 1 AND 3 ^ 3, 2 BETWEEN 1 AND (3 ^ 3), (2 BETWEEN 1 AND 3) ^ 3 union select * from v1;
+2 BETWEEN 1 AND 3 ^ 3 2 BETWEEN 1 AND (3 ^ 3) (2 BETWEEN 1 AND 3) ^ 3
+0 0 2
+create or replace view v1 as select 2 BETWEEN 1 AND 3 BETWEEN 1 AND 3, 2 BETWEEN 1 AND (3 BETWEEN 1 AND 3), (2 BETWEEN 1 AND 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 between 1 and 3 AS `2 BETWEEN 1 AND 3 BETWEEN 1 AND 3`,2 between 1 and 3 between 1 and 3 AS `2 BETWEEN 1 AND (3 BETWEEN 1 AND 3)`,(2 between 1 and 3) between 1 and 3 AS `(2 BETWEEN 1 AND 3) BETWEEN 1 AND 3`
+select 2 BETWEEN 1 AND 3 BETWEEN 1 AND 3, 2 BETWEEN 1 AND (3 BETWEEN 1 AND 3), (2 BETWEEN 1 AND 3) BETWEEN 1 AND 3 union select * from v1;
+2 BETWEEN 1 AND 3 BETWEEN 1 AND 3 2 BETWEEN 1 AND (3 BETWEEN 1 AND 3) (2 BETWEEN 1 AND 3) BETWEEN 1 AND 3
+0 0 1
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 IS FALSE, 2 LIKE 2 ESCAPE (3 IS FALSE), (2 LIKE 2 ESCAPE 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 is false AS `2 LIKE 2 ESCAPE 3 IS FALSE`,2 like 2 escape (3 is false) AS `2 LIKE 2 ESCAPE (3 IS FALSE)`,2 like 2 escape 3 is false AS `(2 LIKE 2 ESCAPE 3) IS FALSE`
+select 2 LIKE 2 ESCAPE 3 IS FALSE, 2 LIKE 2 ESCAPE (3 IS FALSE), (2 LIKE 2 ESCAPE 3) IS FALSE union select * from v1;
+2 LIKE 2 ESCAPE 3 IS FALSE 2 LIKE 2 ESCAPE (3 IS FALSE) (2 LIKE 2 ESCAPE 3) IS FALSE
+0 1 0
+create or replace view v1 as select charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin), charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin)), charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 like 1 escape 3 collate latin1_bin) AS `charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin)`,charset(2 like 1 escape 3 collate latin1_bin) AS `charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin))`,charset((2 like 1 escape 3) collate latin1_bin) AS `charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin)`
+select charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin), charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin)), charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin) union select * from v1;
+charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin) charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin)) charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin)
+binary binary latin1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 IN(0,1), 2 LIKE 1 ESCAPE (3 IN(0,1)), (2 LIKE 1 ESCAPE 3) IN(0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 in (0,1) AS `2 LIKE 1 ESCAPE 3 IN(0,1)`,2 like 1 escape (3 in (0,1)) AS `2 LIKE 1 ESCAPE (3 IN(0,1))`,2 like 1 escape 3 in (0,1) AS `(2 LIKE 1 ESCAPE 3) IN(0,1)`
+select 2 LIKE 1 ESCAPE 3 IN(0,1), 2 LIKE 1 ESCAPE (3 IN(0,1)), (2 LIKE 1 ESCAPE 3) IN(0,1) union select * from v1;
+2 LIKE 1 ESCAPE 3 IN(0,1) 2 LIKE 1 ESCAPE (3 IN(0,1)) (2 LIKE 1 ESCAPE 3) IN(0,1)
+1 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 OR 4, 2 LIKE 1 ESCAPE (3 OR 4), (2 LIKE 1 ESCAPE 3) OR 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 or 4 AS `2 LIKE 1 ESCAPE 3 OR 4`,2 like 1 escape (3 or 4) AS `2 LIKE 1 ESCAPE (3 OR 4)`,2 like 1 escape 3 or 4 AS `(2 LIKE 1 ESCAPE 3) OR 4`
+select 2 LIKE 1 ESCAPE 3 OR 4, 2 LIKE 1 ESCAPE (3 OR 4), (2 LIKE 1 ESCAPE 3) OR 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 OR 4 2 LIKE 1 ESCAPE (3 OR 4) (2 LIKE 1 ESCAPE 3) OR 4
+1 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 || 4, 2 LIKE 1 ESCAPE (3 || 4), (2 LIKE 1 ESCAPE 3) || 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 or 4 AS `2 LIKE 1 ESCAPE 3 || 4`,2 like 1 escape (3 or 4) AS `2 LIKE 1 ESCAPE (3 || 4)`,2 like 1 escape 3 or 4 AS `(2 LIKE 1 ESCAPE 3) || 4`
+select 2 LIKE 1 ESCAPE 3 || 4, 2 LIKE 1 ESCAPE (3 || 4), (2 LIKE 1 ESCAPE 3) || 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 || 4 2 LIKE 1 ESCAPE (3 || 4) (2 LIKE 1 ESCAPE 3) || 4
+1 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 XOR 4, 2 LIKE 1 ESCAPE (3 XOR 4), (2 LIKE 1 ESCAPE 3) XOR 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 xor 4 AS `2 LIKE 1 ESCAPE 3 XOR 4`,2 like 1 escape (3 xor 4) AS `2 LIKE 1 ESCAPE (3 XOR 4)`,2 like 1 escape 3 xor 4 AS `(2 LIKE 1 ESCAPE 3) XOR 4`
+select 2 LIKE 1 ESCAPE 3 XOR 4, 2 LIKE 1 ESCAPE (3 XOR 4), (2 LIKE 1 ESCAPE 3) XOR 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 XOR 4 2 LIKE 1 ESCAPE (3 XOR 4) (2 LIKE 1 ESCAPE 3) XOR 4
+1 0 1
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 AND 0, 2 LIKE 2 ESCAPE (3 AND 0), (2 LIKE 2 ESCAPE 3) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 and 0 AS `2 LIKE 2 ESCAPE 3 AND 0`,2 like 2 escape (3 and 0) AS `2 LIKE 2 ESCAPE (3 AND 0)`,2 like 2 escape 3 and 0 AS `(2 LIKE 2 ESCAPE 3) AND 0`
+select 2 LIKE 2 ESCAPE 3 AND 0, 2 LIKE 2 ESCAPE (3 AND 0), (2 LIKE 2 ESCAPE 3) AND 0 union select * from v1;
+2 LIKE 2 ESCAPE 3 AND 0 2 LIKE 2 ESCAPE (3 AND 0) (2 LIKE 2 ESCAPE 3) AND 0
+0 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 && 0, 2 LIKE 2 ESCAPE (3 && 0), (2 LIKE 2 ESCAPE 3) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 and 0 AS `2 LIKE 2 ESCAPE 3 && 0`,2 like 2 escape (3 and 0) AS `2 LIKE 2 ESCAPE (3 && 0)`,2 like 2 escape 3 and 0 AS `(2 LIKE 2 ESCAPE 3) && 0`
+select 2 LIKE 2 ESCAPE 3 && 0, 2 LIKE 2 ESCAPE (3 && 0), (2 LIKE 2 ESCAPE 3) && 0 union select * from v1;
+2 LIKE 2 ESCAPE 3 && 0 2 LIKE 2 ESCAPE (3 && 0) (2 LIKE 2 ESCAPE 3) && 0
+0 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 = 4, 2 LIKE 2 ESCAPE (3 = 4), (2 LIKE 2 ESCAPE 3) = 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 = 4 AS `2 LIKE 2 ESCAPE 3 = 4`,2 like 2 escape (3 = 4) AS `2 LIKE 2 ESCAPE (3 = 4)`,2 like 2 escape 3 = 4 AS `(2 LIKE 2 ESCAPE 3) = 4`
+select 2 LIKE 2 ESCAPE 3 = 4, 2 LIKE 2 ESCAPE (3 = 4), (2 LIKE 2 ESCAPE 3) = 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 = 4 2 LIKE 2 ESCAPE (3 = 4) (2 LIKE 2 ESCAPE 3) = 4
+0 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 <=> 4, 2 LIKE 2 ESCAPE (3 <=> 4), (2 LIKE 2 ESCAPE 3) <=> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 <=> 4 AS `2 LIKE 2 ESCAPE 3 <=> 4`,2 like 2 escape (3 <=> 4) AS `2 LIKE 2 ESCAPE (3 <=> 4)`,2 like 2 escape 3 <=> 4 AS `(2 LIKE 2 ESCAPE 3) <=> 4`
+select 2 LIKE 2 ESCAPE 3 <=> 4, 2 LIKE 2 ESCAPE (3 <=> 4), (2 LIKE 2 ESCAPE 3) <=> 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 <=> 4 2 LIKE 2 ESCAPE (3 <=> 4) (2 LIKE 2 ESCAPE 3) <=> 4
+0 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 >= 4, 2 LIKE 2 ESCAPE (3 >= 4), (2 LIKE 2 ESCAPE 3) >= 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 >= 4 AS `2 LIKE 2 ESCAPE 3 >= 4`,2 like 2 escape (3 >= 4) AS `2 LIKE 2 ESCAPE (3 >= 4)`,2 like 2 escape 3 >= 4 AS `(2 LIKE 2 ESCAPE 3) >= 4`
+select 2 LIKE 2 ESCAPE 3 >= 4, 2 LIKE 2 ESCAPE (3 >= 4), (2 LIKE 2 ESCAPE 3) >= 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 >= 4 2 LIKE 2 ESCAPE (3 >= 4) (2 LIKE 2 ESCAPE 3) >= 4
+0 1 0
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 <= 4, 2 LIKE 1 ESCAPE (3 <= 4), (2 LIKE 1 ESCAPE 3) <= 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 <= 4 AS `2 LIKE 1 ESCAPE 3 <= 4`,2 like 1 escape (3 <= 4) AS `2 LIKE 1 ESCAPE (3 <= 4)`,2 like 1 escape 3 <= 4 AS `(2 LIKE 1 ESCAPE 3) <= 4`
+select 2 LIKE 1 ESCAPE 3 <= 4, 2 LIKE 1 ESCAPE (3 <= 4), (2 LIKE 1 ESCAPE 3) <= 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 <= 4 2 LIKE 1 ESCAPE (3 <= 4) (2 LIKE 1 ESCAPE 3) <= 4
+1 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 < 4, 2 LIKE 1 ESCAPE (3 < 4), (2 LIKE 1 ESCAPE 3) < 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 < 4 AS `2 LIKE 1 ESCAPE 3 < 4`,2 like 1 escape (3 < 4) AS `2 LIKE 1 ESCAPE (3 < 4)`,2 like 1 escape 3 < 4 AS `(2 LIKE 1 ESCAPE 3) < 4`
+select 2 LIKE 1 ESCAPE 3 < 4, 2 LIKE 1 ESCAPE (3 < 4), (2 LIKE 1 ESCAPE 3) < 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 < 4 2 LIKE 1 ESCAPE (3 < 4) (2 LIKE 1 ESCAPE 3) < 4
+1 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 <> 4, 2 LIKE 1 ESCAPE (3 <> 4), (2 LIKE 1 ESCAPE 3) <> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 <> 4 AS `2 LIKE 1 ESCAPE 3 <> 4`,2 like 1 escape (3 <> 4) AS `2 LIKE 1 ESCAPE (3 <> 4)`,2 like 1 escape 3 <> 4 AS `(2 LIKE 1 ESCAPE 3) <> 4`
+select 2 LIKE 1 ESCAPE 3 <> 4, 2 LIKE 1 ESCAPE (3 <> 4), (2 LIKE 1 ESCAPE 3) <> 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 <> 4 2 LIKE 1 ESCAPE (3 <> 4) (2 LIKE 1 ESCAPE 3) <> 4
+1 0 1
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 > 4, 2 LIKE 2 ESCAPE (3 > 4), (2 LIKE 2 ESCAPE 3) > 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 > 4 AS `2 LIKE 2 ESCAPE 3 > 4`,2 like 2 escape (3 > 4) AS `2 LIKE 2 ESCAPE (3 > 4)`,2 like 2 escape 3 > 4 AS `(2 LIKE 2 ESCAPE 3) > 4`
+select 2 LIKE 2 ESCAPE 3 > 4, 2 LIKE 2 ESCAPE (3 > 4), (2 LIKE 2 ESCAPE 3) > 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 > 4 2 LIKE 2 ESCAPE (3 > 4) (2 LIKE 2 ESCAPE 3) > 4
+0 1 0
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 != 4, 2 LIKE 1 ESCAPE (3 != 4), (2 LIKE 1 ESCAPE 3) != 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 <> 4 AS `2 LIKE 1 ESCAPE 3 != 4`,2 like 1 escape (3 <> 4) AS `2 LIKE 1 ESCAPE (3 != 4)`,2 like 1 escape 3 <> 4 AS `(2 LIKE 1 ESCAPE 3) != 4`
+select 2 LIKE 1 ESCAPE 3 != 4, 2 LIKE 1 ESCAPE (3 != 4), (2 LIKE 1 ESCAPE 3) != 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 != 4 2 LIKE 1 ESCAPE (3 != 4) (2 LIKE 1 ESCAPE 3) != 4
+1 0 1
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 LIKE 4, 2 LIKE 2 ESCAPE (3 LIKE 4), (2 LIKE 2 ESCAPE 3) LIKE 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 like 4 AS `2 LIKE 2 ESCAPE 3 LIKE 4`,2 like 2 escape (3 like 4) AS `2 LIKE 2 ESCAPE (3 LIKE 4)`,2 like 2 escape 3 like 4 AS `(2 LIKE 2 ESCAPE 3) LIKE 4`
+select 2 LIKE 2 ESCAPE 3 LIKE 4, 2 LIKE 2 ESCAPE (3 LIKE 4), (2 LIKE 2 ESCAPE 3) LIKE 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 LIKE 4 2 LIKE 2 ESCAPE (3 LIKE 4) (2 LIKE 2 ESCAPE 3) LIKE 4
+0 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 REGEXP 4, 2 LIKE 2 ESCAPE (3 REGEXP 4), (2 LIKE 2 ESCAPE 3) REGEXP 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 regexp 4 AS `2 LIKE 2 ESCAPE 3 REGEXP 4`,2 like 2 escape (3 regexp 4) AS `2 LIKE 2 ESCAPE (3 REGEXP 4)`,2 like 2 escape 3 regexp 4 AS `(2 LIKE 2 ESCAPE 3) REGEXP 4`
+select 2 LIKE 2 ESCAPE 3 REGEXP 4, 2 LIKE 2 ESCAPE (3 REGEXP 4), (2 LIKE 2 ESCAPE 3) REGEXP 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 REGEXP 4 2 LIKE 2 ESCAPE (3 REGEXP 4) (2 LIKE 2 ESCAPE 3) REGEXP 4
+0 1 0
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 | 4, 2 LIKE 1 ESCAPE (3 | 4), (2 LIKE 1 ESCAPE 3) | 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 | 4 AS `2 LIKE 1 ESCAPE 3 | 4`,2 like 1 escape 3 | 4 AS `2 LIKE 1 ESCAPE (3 | 4)`,(2 like 1 escape 3) | 4 AS `(2 LIKE 1 ESCAPE 3) | 4`
+select 2 LIKE 1 ESCAPE 3 | 4, 2 LIKE 1 ESCAPE (3 | 4), (2 LIKE 1 ESCAPE 3) | 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 | 4 2 LIKE 1 ESCAPE (3 | 4) (2 LIKE 1 ESCAPE 3) | 4
+0 0 4
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 & 4, 2 LIKE 2 ESCAPE (3 & 4), (2 LIKE 2 ESCAPE 3) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 & 4 AS `2 LIKE 2 ESCAPE 3 & 4`,2 like 2 escape 3 & 4 AS `2 LIKE 2 ESCAPE (3 & 4)`,(2 like 2 escape 3) & 4 AS `(2 LIKE 2 ESCAPE 3) & 4`
+select 2 LIKE 2 ESCAPE 3 & 4, 2 LIKE 2 ESCAPE (3 & 4), (2 LIKE 2 ESCAPE 3) & 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 & 4 2 LIKE 2 ESCAPE (3 & 4) (2 LIKE 2 ESCAPE 3) & 4
+1 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 1 << 1, 2 LIKE 2 ESCAPE (1 << 1), (2 LIKE 2 ESCAPE 1) << 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 1 << 1 AS `2 LIKE 2 ESCAPE 1 << 1`,2 like 2 escape 1 << 1 AS `2 LIKE 2 ESCAPE (1 << 1)`,(2 like 2 escape 1) << 1 AS `(2 LIKE 2 ESCAPE 1) << 1`
+select 2 LIKE 2 ESCAPE 1 << 1, 2 LIKE 2 ESCAPE (1 << 1), (2 LIKE 2 ESCAPE 1) << 1 union select * from v1;
+2 LIKE 2 ESCAPE 1 << 1 2 LIKE 2 ESCAPE (1 << 1) (2 LIKE 2 ESCAPE 1) << 1
+1 1 2
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 >> 4, 2 LIKE 2 ESCAPE (3 >> 4), (2 LIKE 2 ESCAPE 3) >> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 >> 4 AS `2 LIKE 2 ESCAPE 3 >> 4`,2 like 2 escape 3 >> 4 AS `2 LIKE 2 ESCAPE (3 >> 4)`,(2 like 2 escape 3) >> 4 AS `(2 LIKE 2 ESCAPE 3) >> 4`
+select 2 LIKE 2 ESCAPE 3 >> 4, 2 LIKE 2 ESCAPE (3 >> 4), (2 LIKE 2 ESCAPE 3) >> 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 >> 4 2 LIKE 2 ESCAPE (3 >> 4) (2 LIKE 2 ESCAPE 3) >> 4
+1 1 0
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY, 2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY), (2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 + interval 1 day AS `2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY`,2 like 1 escape 3 + interval 1 day AS `2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY)`,(2 like 1 escape 3) + interval 1 day AS `(2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY`
+select 2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY, 2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY), (2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY union select * from v1;
+2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY 2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY) (2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY
+0 0 NULL
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 + 4, 2 LIKE 1 ESCAPE (3 + 4), (2 LIKE 1 ESCAPE 3) + 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 + 4 AS `2 LIKE 1 ESCAPE 3 + 4`,2 like 1 escape 3 + 4 AS `2 LIKE 1 ESCAPE (3 + 4)`,(2 like 1 escape 3) + 4 AS `(2 LIKE 1 ESCAPE 3) + 4`
+select 2 LIKE 1 ESCAPE 3 + 4, 2 LIKE 1 ESCAPE (3 + 4), (2 LIKE 1 ESCAPE 3) + 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 + 4 2 LIKE 1 ESCAPE (3 + 4) (2 LIKE 1 ESCAPE 3) + 4
+0 0 4
+create or replace view v1 as select 2 LIKE 2 ESCAPE 1 - 1, 2 LIKE 2 ESCAPE (1 - 1), (2 LIKE 2 ESCAPE 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 1 - 1 AS `2 LIKE 2 ESCAPE 1 - 1`,2 like 2 escape 1 - 1 AS `2 LIKE 2 ESCAPE (1 - 1)`,(2 like 2 escape 1) - 1 AS `(2 LIKE 2 ESCAPE 1) - 1`
+select 2 LIKE 2 ESCAPE 1 - 1, 2 LIKE 2 ESCAPE (1 - 1), (2 LIKE 2 ESCAPE 1) - 1 union select * from v1;
+2 LIKE 2 ESCAPE 1 - 1 2 LIKE 2 ESCAPE (1 - 1) (2 LIKE 2 ESCAPE 1) - 1
+1 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 * 0, 2 LIKE 2 ESCAPE (3 * 0), (2 LIKE 2 ESCAPE 3) * 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 * 0 AS `2 LIKE 2 ESCAPE 3 * 0`,2 like 2 escape 3 * 0 AS `2 LIKE 2 ESCAPE (3 * 0)`,(2 like 2 escape 3) * 0 AS `(2 LIKE 2 ESCAPE 3) * 0`
+select 2 LIKE 2 ESCAPE 3 * 0, 2 LIKE 2 ESCAPE (3 * 0), (2 LIKE 2 ESCAPE 3) * 0 union select * from v1;
+2 LIKE 2 ESCAPE 3 * 0 2 LIKE 2 ESCAPE (3 * 0) (2 LIKE 2 ESCAPE 3) * 0
+1 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 DIV 3, 2 LIKE 2 ESCAPE (3 DIV 3), (2 LIKE 2 ESCAPE 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 DIV 3 AS `2 LIKE 2 ESCAPE 3 DIV 3`,2 like 2 escape 3 DIV 3 AS `2 LIKE 2 ESCAPE (3 DIV 3)`,(2 like 2 escape 3) DIV 3 AS `(2 LIKE 2 ESCAPE 3) DIV 3`
+select 2 LIKE 2 ESCAPE 3 DIV 3, 2 LIKE 2 ESCAPE (3 DIV 3), (2 LIKE 2 ESCAPE 3) DIV 3 union select * from v1;
+2 LIKE 2 ESCAPE 3 DIV 3 2 LIKE 2 ESCAPE (3 DIV 3) (2 LIKE 2 ESCAPE 3) DIV 3
+1 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 MOD 1, 2 LIKE 2 ESCAPE (3 MOD 1), (2 LIKE 2 ESCAPE 3) MOD 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 MOD 1 AS `2 LIKE 2 ESCAPE 3 MOD 1`,2 like 2 escape 3 MOD 1 AS `2 LIKE 2 ESCAPE (3 MOD 1)`,(2 like 2 escape 3) MOD 1 AS `(2 LIKE 2 ESCAPE 3) MOD 1`
+select 2 LIKE 2 ESCAPE 3 MOD 1, 2 LIKE 2 ESCAPE (3 MOD 1), (2 LIKE 2 ESCAPE 3) MOD 1 union select * from v1;
+2 LIKE 2 ESCAPE 3 MOD 1 2 LIKE 2 ESCAPE (3 MOD 1) (2 LIKE 2 ESCAPE 3) MOD 1
+1 1 0
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 % 1, 2 LIKE 2 ESCAPE (3 % 1), (2 LIKE 2 ESCAPE 3) % 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 MOD 1 AS `2 LIKE 2 ESCAPE 3 % 1`,2 like 2 escape 3 MOD 1 AS `2 LIKE 2 ESCAPE (3 % 1)`,(2 like 2 escape 3) MOD 1 AS `(2 LIKE 2 ESCAPE 3) % 1`
+select 2 LIKE 2 ESCAPE 3 % 1, 2 LIKE 2 ESCAPE (3 % 1), (2 LIKE 2 ESCAPE 3) % 1 union select * from v1;
+2 LIKE 2 ESCAPE 3 % 1 2 LIKE 2 ESCAPE (3 % 1) (2 LIKE 2 ESCAPE 3) % 1
+1 1 0
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 ^ 4, 2 LIKE 1 ESCAPE (3 ^ 4), (2 LIKE 1 ESCAPE 3) ^ 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 ^ 4 AS `2 LIKE 1 ESCAPE 3 ^ 4`,2 like 1 escape 3 ^ 4 AS `2 LIKE 1 ESCAPE (3 ^ 4)`,(2 like 1 escape 3) ^ 4 AS `(2 LIKE 1 ESCAPE 3) ^ 4`
+select 2 LIKE 1 ESCAPE 3 ^ 4, 2 LIKE 1 ESCAPE (3 ^ 4), (2 LIKE 1 ESCAPE 3) ^ 4 union select * from v1;
+2 LIKE 1 ESCAPE 3 ^ 4 2 LIKE 1 ESCAPE (3 ^ 4) (2 LIKE 1 ESCAPE 3) ^ 4
+0 0 4
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4, 2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4), (2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 2 escape 3 between 2 and 4 AS `2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4`,2 like 2 escape (3 between 2 and 4) AS `2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4)`,2 like 2 escape 3 between 2 and 4 AS `(2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4`
+select 2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4, 2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4), (2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4 union select * from v1;
+2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4 2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4) (2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4
+0 1 0
+create or replace view v1 as select NOT 2 IN (SELECT 0 UNION SELECT 2), NOT (2 IN (SELECT 0 UNION SELECT 2)), (NOT 2) IN (SELECT 0 UNION SELECT 2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !(2 in (select 0 union select 2)) AS `NOT 2 IN (SELECT 0 UNION SELECT 2)`,!(2 in (select 0 union select 2)) AS `NOT (2 IN (SELECT 0 UNION SELECT 2))`,!2 in (select 0 union select 2) AS `(NOT 2) IN (SELECT 0 UNION SELECT 2)`
+select NOT 2 IN (SELECT 0 UNION SELECT 2), NOT (2 IN (SELECT 0 UNION SELECT 2)), (NOT 2) IN (SELECT 0 UNION SELECT 2) union select * from v1;
+NOT 2 IN (SELECT 0 UNION SELECT 2) NOT (2 IN (SELECT 0 UNION SELECT 2)) (NOT 2) IN (SELECT 0 UNION SELECT 2)
+0 0 1
+create or replace view v1 as select - 2 IN (SELECT 2 UNION SELECT 1), - (2 IN (SELECT 2 UNION SELECT 1)), (- 2) IN (SELECT 2 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -2 in (select 2 union select 1) AS `- 2 IN (SELECT 2 UNION SELECT 1)`,-(2 in (select 2 union select 1)) AS `- (2 IN (SELECT 2 UNION SELECT 1))`,-2 in (select 2 union select 1) AS `(- 2) IN (SELECT 2 UNION SELECT 1)`
+select - 2 IN (SELECT 2 UNION SELECT 1), - (2 IN (SELECT 2 UNION SELECT 1)), (- 2) IN (SELECT 2 UNION SELECT 1) union select * from v1;
+- 2 IN (SELECT 2 UNION SELECT 1) - (2 IN (SELECT 2 UNION SELECT 1)) (- 2) IN (SELECT 2 UNION SELECT 1)
+0 -1 0
+create or replace view v1 as select ~ 2 IN (SELECT 0 UNION SELECT 1), ~ (2 IN (SELECT 0 UNION SELECT 1)), (~ 2) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select ~2 in (select 0 union select 1) AS `~ 2 IN (SELECT 0 UNION SELECT 1)`,~(2 in (select 0 union select 1)) AS `~ (2 IN (SELECT 0 UNION SELECT 1))`,~2 in (select 0 union select 1) AS `(~ 2) IN (SELECT 0 UNION SELECT 1)`
+select ~ 2 IN (SELECT 0 UNION SELECT 1), ~ (2 IN (SELECT 0 UNION SELECT 1)), (~ 2) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+~ 2 IN (SELECT 0 UNION SELECT 1) ~ (2 IN (SELECT 0 UNION SELECT 1)) (~ 2) IN (SELECT 0 UNION SELECT 1)
+0 18446744073709551615 0
+create or replace view v1 as select ! 2 IN (SELECT 0 UNION SELECT 2), ! (2 IN (SELECT 0 UNION SELECT 2)), (! 2) IN (SELECT 0 UNION SELECT 2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !2 in (select 0 union select 2) AS `! 2 IN (SELECT 0 UNION SELECT 2)`,!(2 in (select 0 union select 2)) AS `! (2 IN (SELECT 0 UNION SELECT 2))`,!2 in (select 0 union select 2) AS `(! 2) IN (SELECT 0 UNION SELECT 2)`
+select ! 2 IN (SELECT 0 UNION SELECT 2), ! (2 IN (SELECT 0 UNION SELECT 2)), (! 2) IN (SELECT 0 UNION SELECT 2) union select * from v1;
+! 2 IN (SELECT 0 UNION SELECT 2) ! (2 IN (SELECT 0 UNION SELECT 2)) (! 2) IN (SELECT 0 UNION SELECT 2)
+1 0 1
+create or replace view v1 as select BINARY 'c' IN (SELECT 'C' UNION SELECT 'X'), BINARY ('c' IN (SELECT 'C' UNION SELECT 'X')), (BINARY 'c') IN (SELECT 'C' UNION SELECT 'X');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast('c' as char charset binary) in (select 'C' union select 'X') AS `BINARY 'c' IN (SELECT 'C' UNION SELECT 'X')`,cast('c' in (select 'C' union select 'X') as char charset binary) AS `BINARY ('c' IN (SELECT 'C' UNION SELECT 'X'))`,cast('c' as char charset binary) in (select 'C' union select 'X') AS `(BINARY 'c') IN (SELECT 'C' UNION SELECT 'X')`
+select BINARY 'c' IN (SELECT 'C' UNION SELECT 'X'), BINARY ('c' IN (SELECT 'C' UNION SELECT 'X')), (BINARY 'c') IN (SELECT 'C' UNION SELECT 'X') union select * from v1;
+BINARY 'c' IN (SELECT 'C' UNION SELECT 'X') BINARY ('c' IN (SELECT 'C' UNION SELECT 'X')) (BINARY 'c') IN (SELECT 'C' UNION SELECT 'X')
+0 1 0
+create or replace view v1 as select 0 OR 3 IN (SELECT 3 UNION SELECT 10), 0 OR (3 IN (SELECT 3 UNION SELECT 10)), (0 OR 3) IN (SELECT 3 UNION SELECT 10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 in (select 3 union select 10) AS `0 OR 3 IN (SELECT 3 UNION SELECT 10)`,0 or 3 in (select 3 union select 10) AS `0 OR (3 IN (SELECT 3 UNION SELECT 10))`,(0 or 3) in (select 3 union select 10) AS `(0 OR 3) IN (SELECT 3 UNION SELECT 10)`
+select 0 OR 3 IN (SELECT 3 UNION SELECT 10), 0 OR (3 IN (SELECT 3 UNION SELECT 10)), (0 OR 3) IN (SELECT 3 UNION SELECT 10) union select * from v1;
+0 OR 3 IN (SELECT 3 UNION SELECT 10) 0 OR (3 IN (SELECT 3 UNION SELECT 10)) (0 OR 3) IN (SELECT 3 UNION SELECT 10)
+1 1 0
+create or replace view v1 as select 0 || 3 IN (SELECT 3 UNION SELECT 10), 0 || (3 IN (SELECT 3 UNION SELECT 10)), (0 || 3) IN (SELECT 3 UNION SELECT 10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 or 3 in (select 3 union select 10) AS `0 || 3 IN (SELECT 3 UNION SELECT 10)`,0 or 3 in (select 3 union select 10) AS `0 || (3 IN (SELECT 3 UNION SELECT 10))`,(0 or 3) in (select 3 union select 10) AS `(0 || 3) IN (SELECT 3 UNION SELECT 10)`
+select 0 || 3 IN (SELECT 3 UNION SELECT 10), 0 || (3 IN (SELECT 3 UNION SELECT 10)), (0 || 3) IN (SELECT 3 UNION SELECT 10) union select * from v1;
+0 || 3 IN (SELECT 3 UNION SELECT 10) 0 || (3 IN (SELECT 3 UNION SELECT 10)) (0 || 3) IN (SELECT 3 UNION SELECT 10)
+1 1 0
+create or replace view v1 as select 2 XOR 3 IN (SELECT 4 UNION SELECT 5), 2 XOR (3 IN (SELECT 4 UNION SELECT 5)), (2 XOR 3) IN (SELECT 4 UNION SELECT 5);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor 3 in (select 4 union select 5) AS `2 XOR 3 IN (SELECT 4 UNION SELECT 5)`,2 xor 3 in (select 4 union select 5) AS `2 XOR (3 IN (SELECT 4 UNION SELECT 5))`,(2 xor 3) in (select 4 union select 5) AS `(2 XOR 3) IN (SELECT 4 UNION SELECT 5)`
+select 2 XOR 3 IN (SELECT 4 UNION SELECT 5), 2 XOR (3 IN (SELECT 4 UNION SELECT 5)), (2 XOR 3) IN (SELECT 4 UNION SELECT 5) union select * from v1;
+2 XOR 3 IN (SELECT 4 UNION SELECT 5) 2 XOR (3 IN (SELECT 4 UNION SELECT 5)) (2 XOR 3) IN (SELECT 4 UNION SELECT 5)
+1 1 0
+create or replace view v1 as select 2 AND 3 IN (SELECT 0 UNION SELECT 1), 2 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 AND 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 in (select 0 union select 1) AS `2 AND 3 IN (SELECT 0 UNION SELECT 1)`,2 and 3 in (select 0 union select 1) AS `2 AND (3 IN (SELECT 0 UNION SELECT 1))`,(2 and 3) in (select 0 union select 1) AS `(2 AND 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 AND 3 IN (SELECT 0 UNION SELECT 1), 2 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 AND 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 AND 3 IN (SELECT 0 UNION SELECT 1) 2 AND (3 IN (SELECT 0 UNION SELECT 1)) (2 AND 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 && 3 IN (SELECT 0 UNION SELECT 1), 2 && (3 IN (SELECT 0 UNION SELECT 1)), (2 && 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 and 3 in (select 0 union select 1) AS `2 && 3 IN (SELECT 0 UNION SELECT 1)`,2 and 3 in (select 0 union select 1) AS `2 && (3 IN (SELECT 0 UNION SELECT 1))`,(2 and 3) in (select 0 union select 1) AS `(2 && 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 && 3 IN (SELECT 0 UNION SELECT 1), 2 && (3 IN (SELECT 0 UNION SELECT 1)), (2 && 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 && 3 IN (SELECT 0 UNION SELECT 1) 2 && (3 IN (SELECT 0 UNION SELECT 1)) (2 && 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 = 3 IN (SELECT 0 UNION SELECT 1), 2 = (3 IN (SELECT 0 UNION SELECT 1)), (2 = 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = 3 in (select 0 union select 1) AS `2 = 3 IN (SELECT 0 UNION SELECT 1)`,2 = 3 in (select 0 union select 1) AS `2 = (3 IN (SELECT 0 UNION SELECT 1))`,(2 = 3) in (select 0 union select 1) AS `(2 = 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 = 3 IN (SELECT 0 UNION SELECT 1), 2 = (3 IN (SELECT 0 UNION SELECT 1)), (2 = 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 = 3 IN (SELECT 0 UNION SELECT 1) 2 = (3 IN (SELECT 0 UNION SELECT 1)) (2 = 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 <=> 3 IN (SELECT 0 UNION SELECT 1), 2 <=> (3 IN (SELECT 0 UNION SELECT 1)), (2 <=> 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> 3 in (select 0 union select 1) AS `2 <=> 3 IN (SELECT 0 UNION SELECT 1)`,2 <=> 3 in (select 0 union select 1) AS `2 <=> (3 IN (SELECT 0 UNION SELECT 1))`,(2 <=> 3) in (select 0 union select 1) AS `(2 <=> 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 <=> 3 IN (SELECT 0 UNION SELECT 1), 2 <=> (3 IN (SELECT 0 UNION SELECT 1)), (2 <=> 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 <=> 3 IN (SELECT 0 UNION SELECT 1) 2 <=> (3 IN (SELECT 0 UNION SELECT 1)) (2 <=> 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 >= 3 IN (SELECT 1 UNION SELECT 1), 2 >= (3 IN (SELECT 1 UNION SELECT 1)), (2 >= 3) IN (SELECT 1 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= 3 in (select 1 union select 1) AS `2 >= 3 IN (SELECT 1 UNION SELECT 1)`,2 >= 3 in (select 1 union select 1) AS `2 >= (3 IN (SELECT 1 UNION SELECT 1))`,(2 >= 3) in (select 1 union select 1) AS `(2 >= 3) IN (SELECT 1 UNION SELECT 1)`
+select 2 >= 3 IN (SELECT 1 UNION SELECT 1), 2 >= (3 IN (SELECT 1 UNION SELECT 1)), (2 >= 3) IN (SELECT 1 UNION SELECT 1) union select * from v1;
+2 >= 3 IN (SELECT 1 UNION SELECT 1) 2 >= (3 IN (SELECT 1 UNION SELECT 1)) (2 >= 3) IN (SELECT 1 UNION SELECT 1)
+1 1 0
+create or replace view v1 as select 2 <= 3 IN (SELECT 0 UNION SELECT 1), 2 <= (3 IN (SELECT 0 UNION SELECT 1)), (2 <= 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= 3 in (select 0 union select 1) AS `2 <= 3 IN (SELECT 0 UNION SELECT 1)`,2 <= 3 in (select 0 union select 1) AS `2 <= (3 IN (SELECT 0 UNION SELECT 1))`,(2 <= 3) in (select 0 union select 1) AS `(2 <= 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 <= 3 IN (SELECT 0 UNION SELECT 1), 2 <= (3 IN (SELECT 0 UNION SELECT 1)), (2 <= 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 <= 3 IN (SELECT 0 UNION SELECT 1) 2 <= (3 IN (SELECT 0 UNION SELECT 1)) (2 <= 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 < 3 IN (SELECT 0 UNION SELECT 1), 2 < (3 IN (SELECT 0 UNION SELECT 1)), (2 < 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < 3 in (select 0 union select 1) AS `2 < 3 IN (SELECT 0 UNION SELECT 1)`,2 < 3 in (select 0 union select 1) AS `2 < (3 IN (SELECT 0 UNION SELECT 1))`,(2 < 3) in (select 0 union select 1) AS `(2 < 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 < 3 IN (SELECT 0 UNION SELECT 1), 2 < (3 IN (SELECT 0 UNION SELECT 1)), (2 < 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 < 3 IN (SELECT 0 UNION SELECT 1) 2 < (3 IN (SELECT 0 UNION SELECT 1)) (2 < 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 <> 3 IN (SELECT 0 UNION SELECT 0), 2 <> (3 IN (SELECT 0 UNION SELECT 0)), (2 <> 3) IN (SELECT 0 UNION SELECT 0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 in (select 0 union select 0) AS `2 <> 3 IN (SELECT 0 UNION SELECT 0)`,2 <> 3 in (select 0 union select 0) AS `2 <> (3 IN (SELECT 0 UNION SELECT 0))`,(2 <> 3) in (select 0 union select 0) AS `(2 <> 3) IN (SELECT 0 UNION SELECT 0)`
+select 2 <> 3 IN (SELECT 0 UNION SELECT 0), 2 <> (3 IN (SELECT 0 UNION SELECT 0)), (2 <> 3) IN (SELECT 0 UNION SELECT 0) union select * from v1;
+2 <> 3 IN (SELECT 0 UNION SELECT 0) 2 <> (3 IN (SELECT 0 UNION SELECT 0)) (2 <> 3) IN (SELECT 0 UNION SELECT 0)
+1 1 0
+create or replace view v1 as select 2 > 3 IN (SELECT 1 UNION SELECT 1), 2 > (3 IN (SELECT 1 UNION SELECT 1)), (2 > 3) IN (SELECT 1 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 > 3 in (select 1 union select 1) AS `2 > 3 IN (SELECT 1 UNION SELECT 1)`,2 > 3 in (select 1 union select 1) AS `2 > (3 IN (SELECT 1 UNION SELECT 1))`,(2 > 3) in (select 1 union select 1) AS `(2 > 3) IN (SELECT 1 UNION SELECT 1)`
+select 2 > 3 IN (SELECT 1 UNION SELECT 1), 2 > (3 IN (SELECT 1 UNION SELECT 1)), (2 > 3) IN (SELECT 1 UNION SELECT 1) union select * from v1;
+2 > 3 IN (SELECT 1 UNION SELECT 1) 2 > (3 IN (SELECT 1 UNION SELECT 1)) (2 > 3) IN (SELECT 1 UNION SELECT 1)
+1 1 0
+create or replace view v1 as select 2 != 3 IN (SELECT 0 UNION SELECT 0), 2 != (3 IN (SELECT 0 UNION SELECT 0)), (2 != 3) IN (SELECT 0 UNION SELECT 0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <> 3 in (select 0 union select 0) AS `2 != 3 IN (SELECT 0 UNION SELECT 0)`,2 <> 3 in (select 0 union select 0) AS `2 != (3 IN (SELECT 0 UNION SELECT 0))`,(2 <> 3) in (select 0 union select 0) AS `(2 != 3) IN (SELECT 0 UNION SELECT 0)`
+select 2 != 3 IN (SELECT 0 UNION SELECT 0), 2 != (3 IN (SELECT 0 UNION SELECT 0)), (2 != 3) IN (SELECT 0 UNION SELECT 0) union select * from v1;
+2 != 3 IN (SELECT 0 UNION SELECT 0) 2 != (3 IN (SELECT 0 UNION SELECT 0)) (2 != 3) IN (SELECT 0 UNION SELECT 0)
+1 1 0
+create or replace view v1 as select 2 LIKE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 3 in (select 0 union select 1) AS `2 LIKE 3 IN (SELECT 0 UNION SELECT 1)`,2 like (3 in (select 0 union select 1)) AS `2 LIKE (3 IN (SELECT 0 UNION SELECT 1))`,2 like 3 in (select 0 union select 1) AS `(2 LIKE 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 LIKE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 LIKE 3 IN (SELECT 0 UNION SELECT 1) 2 LIKE (3 IN (SELECT 0 UNION SELECT 1)) (2 LIKE 3) IN (SELECT 0 UNION SELECT 1)
+1 0 1
+create or replace view v1 as select 2 REGEXP 3 IN (SELECT 0 UNION SELECT 1), 2 REGEXP (3 IN (SELECT 0 UNION SELECT 1)), (2 REGEXP 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp 3 in (select 0 union select 1) AS `2 REGEXP 3 IN (SELECT 0 UNION SELECT 1)`,2 regexp (3 in (select 0 union select 1)) AS `2 REGEXP (3 IN (SELECT 0 UNION SELECT 1))`,2 regexp 3 in (select 0 union select 1) AS `(2 REGEXP 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 REGEXP 3 IN (SELECT 0 UNION SELECT 1), 2 REGEXP (3 IN (SELECT 0 UNION SELECT 1)), (2 REGEXP 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 REGEXP 3 IN (SELECT 0 UNION SELECT 1) 2 REGEXP (3 IN (SELECT 0 UNION SELECT 1)) (2 REGEXP 3) IN (SELECT 0 UNION SELECT 1)
+1 0 1
+create or replace view v1 as select 2 | 3 IN (SELECT 0 UNION SELECT 1), 2 | (3 IN (SELECT 0 UNION SELECT 1)), (2 | 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | 3 in (select 0 union select 1) AS `2 | 3 IN (SELECT 0 UNION SELECT 1)`,2 | (3 in (select 0 union select 1)) AS `2 | (3 IN (SELECT 0 UNION SELECT 1))`,2 | 3 in (select 0 union select 1) AS `(2 | 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 | 3 IN (SELECT 0 UNION SELECT 1), 2 | (3 IN (SELECT 0 UNION SELECT 1)), (2 | 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 | 3 IN (SELECT 0 UNION SELECT 1) 2 | (3 IN (SELECT 0 UNION SELECT 1)) (2 | 3) IN (SELECT 0 UNION SELECT 1)
+0 2 0
+create or replace view v1 as select 2 & 4 IN (SELECT 0 UNION SELECT 1), 2 & (4 IN (SELECT 0 UNION SELECT 1)), (2 & 4) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & 4 in (select 0 union select 1) AS `2 & 4 IN (SELECT 0 UNION SELECT 1)`,2 & (4 in (select 0 union select 1)) AS `2 & (4 IN (SELECT 0 UNION SELECT 1))`,2 & 4 in (select 0 union select 1) AS `(2 & 4) IN (SELECT 0 UNION SELECT 1)`
+select 2 & 4 IN (SELECT 0 UNION SELECT 1), 2 & (4 IN (SELECT 0 UNION SELECT 1)), (2 & 4) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 & 4 IN (SELECT 0 UNION SELECT 1) 2 & (4 IN (SELECT 0 UNION SELECT 1)) (2 & 4) IN (SELECT 0 UNION SELECT 1)
+1 0 1
+create or replace view v1 as select 2 << 3 IN (SELECT 0 UNION SELECT 1), 2 << (3 IN (SELECT 0 UNION SELECT 1)), (2 << 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << 3 in (select 0 union select 1) AS `2 << 3 IN (SELECT 0 UNION SELECT 1)`,2 << (3 in (select 0 union select 1)) AS `2 << (3 IN (SELECT 0 UNION SELECT 1))`,2 << 3 in (select 0 union select 1) AS `(2 << 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 << 3 IN (SELECT 0 UNION SELECT 1), 2 << (3 IN (SELECT 0 UNION SELECT 1)), (2 << 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 << 3 IN (SELECT 0 UNION SELECT 1) 2 << (3 IN (SELECT 0 UNION SELECT 1)) (2 << 3) IN (SELECT 0 UNION SELECT 1)
+0 2 0
+create or replace view v1 as select 2 >> 3 IN (SELECT 0 UNION SELECT 1), 2 >> (3 IN (SELECT 0 UNION SELECT 1)), (2 >> 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> 3 in (select 0 union select 1) AS `2 >> 3 IN (SELECT 0 UNION SELECT 1)`,2 >> (3 in (select 0 union select 1)) AS `2 >> (3 IN (SELECT 0 UNION SELECT 1))`,2 >> 3 in (select 0 union select 1) AS `(2 >> 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 >> 3 IN (SELECT 0 UNION SELECT 1), 2 >> (3 IN (SELECT 0 UNION SELECT 1)), (2 >> 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 >> 3 IN (SELECT 0 UNION SELECT 1) 2 >> (3 IN (SELECT 0 UNION SELECT 1)) (2 >> 3) IN (SELECT 0 UNION SELECT 1)
+1 2 1
+create or replace view v1 as select 2 + 3 IN (SELECT 0 UNION SELECT 1), 2 + (3 IN (SELECT 0 UNION SELECT 1)), (2 + 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + 3 in (select 0 union select 1) AS `2 + 3 IN (SELECT 0 UNION SELECT 1)`,2 + (3 in (select 0 union select 1)) AS `2 + (3 IN (SELECT 0 UNION SELECT 1))`,2 + 3 in (select 0 union select 1) AS `(2 + 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 + 3 IN (SELECT 0 UNION SELECT 1), 2 + (3 IN (SELECT 0 UNION SELECT 1)), (2 + 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 + 3 IN (SELECT 0 UNION SELECT 1) 2 + (3 IN (SELECT 0 UNION SELECT 1)) (2 + 3) IN (SELECT 0 UNION SELECT 1)
+0 2 0
+create or replace view v1 as select 2 - 3 IN (SELECT 0 UNION SELECT 1), 2 - (3 IN (SELECT 0 UNION SELECT 1)), (2 - 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - 3 in (select 0 union select 1) AS `2 - 3 IN (SELECT 0 UNION SELECT 1)`,2 - (3 in (select 0 union select 1)) AS `2 - (3 IN (SELECT 0 UNION SELECT 1))`,2 - 3 in (select 0 union select 1) AS `(2 - 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 - 3 IN (SELECT 0 UNION SELECT 1), 2 - (3 IN (SELECT 0 UNION SELECT 1)), (2 - 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 - 3 IN (SELECT 0 UNION SELECT 1) 2 - (3 IN (SELECT 0 UNION SELECT 1)) (2 - 3) IN (SELECT 0 UNION SELECT 1)
+0 2 0
+create or replace view v1 as select 2 * 0 IN (SELECT 0 UNION SELECT 1), 2 * (0 IN (SELECT 0 UNION SELECT 1)), (2 * 0) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * 0 in (select 0 union select 1) AS `2 * 0 IN (SELECT 0 UNION SELECT 1)`,2 * (0 in (select 0 union select 1)) AS `2 * (0 IN (SELECT 0 UNION SELECT 1))`,2 * 0 in (select 0 union select 1) AS `(2 * 0) IN (SELECT 0 UNION SELECT 1)`
+select 2 * 0 IN (SELECT 0 UNION SELECT 1), 2 * (0 IN (SELECT 0 UNION SELECT 1)), (2 * 0) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 * 0 IN (SELECT 0 UNION SELECT 1) 2 * (0 IN (SELECT 0 UNION SELECT 1)) (2 * 0) IN (SELECT 0 UNION SELECT 1)
+1 2 1
+create or replace view v1 as select 2 / 3 IN (SELECT 0 UNION SELECT 1), 2 / (3 IN (SELECT 0 UNION SELECT 1)), (2 / 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / 3 in (select 0 union select 1) AS `2 / 3 IN (SELECT 0 UNION SELECT 1)`,2 / (3 in (select 0 union select 1)) AS `2 / (3 IN (SELECT 0 UNION SELECT 1))`,2 / 3 in (select 0 union select 1) AS `(2 / 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 / 3 IN (SELECT 0 UNION SELECT 1), 2 / (3 IN (SELECT 0 UNION SELECT 1)), (2 / 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 / 3 IN (SELECT 0 UNION SELECT 1) 2 / (3 IN (SELECT 0 UNION SELECT 1)) (2 / 3) IN (SELECT 0 UNION SELECT 1)
+0 NULL 0
+create or replace view v1 as select 2 DIV 3 IN (SELECT 0 UNION SELECT 1), 2 DIV (3 IN (SELECT 0 UNION SELECT 1)), (2 DIV 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV 3 in (select 0 union select 1) AS `2 DIV 3 IN (SELECT 0 UNION SELECT 1)`,2 DIV (3 in (select 0 union select 1)) AS `2 DIV (3 IN (SELECT 0 UNION SELECT 1))`,2 DIV 3 in (select 0 union select 1) AS `(2 DIV 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 DIV 3 IN (SELECT 0 UNION SELECT 1), 2 DIV (3 IN (SELECT 0 UNION SELECT 1)), (2 DIV 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 DIV 3 IN (SELECT 0 UNION SELECT 1) 2 DIV (3 IN (SELECT 0 UNION SELECT 1)) (2 DIV 3) IN (SELECT 0 UNION SELECT 1)
+1 NULL 1
+create or replace view v1 as select 2 MOD 3 IN (SELECT 0 UNION SELECT 1), 2 MOD (3 IN (SELECT 0 UNION SELECT 1)), (2 MOD 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 in (select 0 union select 1) AS `2 MOD 3 IN (SELECT 0 UNION SELECT 1)`,2 MOD (3 in (select 0 union select 1)) AS `2 MOD (3 IN (SELECT 0 UNION SELECT 1))`,2 MOD 3 in (select 0 union select 1) AS `(2 MOD 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 MOD 3 IN (SELECT 0 UNION SELECT 1), 2 MOD (3 IN (SELECT 0 UNION SELECT 1)), (2 MOD 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 MOD 3 IN (SELECT 0 UNION SELECT 1) 2 MOD (3 IN (SELECT 0 UNION SELECT 1)) (2 MOD 3) IN (SELECT 0 UNION SELECT 1)
+0 NULL 0
+create or replace view v1 as select 2 % 3 IN (SELECT 0 UNION SELECT 1), 2 % (3 IN (SELECT 0 UNION SELECT 1)), (2 % 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD 3 in (select 0 union select 1) AS `2 % 3 IN (SELECT 0 UNION SELECT 1)`,2 MOD (3 in (select 0 union select 1)) AS `2 % (3 IN (SELECT 0 UNION SELECT 1))`,2 MOD 3 in (select 0 union select 1) AS `(2 % 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 % 3 IN (SELECT 0 UNION SELECT 1), 2 % (3 IN (SELECT 0 UNION SELECT 1)), (2 % 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 % 3 IN (SELECT 0 UNION SELECT 1) 2 % (3 IN (SELECT 0 UNION SELECT 1)) (2 % 3) IN (SELECT 0 UNION SELECT 1)
+0 NULL 0
+create or replace view v1 as select 2 ^ 3 IN (SELECT 0 UNION SELECT 1), 2 ^ (3 IN (SELECT 0 UNION SELECT 1)), (2 ^ 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ 3 in (select 0 union select 1) AS `2 ^ 3 IN (SELECT 0 UNION SELECT 1)`,2 ^ (3 in (select 0 union select 1)) AS `2 ^ (3 IN (SELECT 0 UNION SELECT 1))`,2 ^ 3 in (select 0 union select 1) AS `(2 ^ 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 ^ 3 IN (SELECT 0 UNION SELECT 1), 2 ^ (3 IN (SELECT 0 UNION SELECT 1)), (2 ^ 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 ^ 3 IN (SELECT 0 UNION SELECT 1) 2 ^ (3 IN (SELECT 0 UNION SELECT 1)) (2 ^ 3) IN (SELECT 0 UNION SELECT 1)
+1 2 1
+create or replace view v1 as select 2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1), 2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and 3 in (select 0 union select 1) AS `2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1)`,2 between 1 and 3 in (select 0 union select 1) AS `2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1))`,(2 between 1 and 3) in (select 0 union select 1) AS `(2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1), 2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1) 2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1)) (2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1)
+0 0 1
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like 1 escape 3 in (select 0 union select 1) AS `2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1)`,2 like 1 escape (3 in (select 0 union select 1)) AS `2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1))`,2 like 1 escape 3 in (select 0 union select 1) AS `(2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1)`
+select 2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1) 2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1)) (2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1)
+1 0 1
+create or replace view v1 as select 3 BETWEEN 1 AND 2 AND NULL, 3 BETWEEN (1 AND 2) AND NULL, 3 BETWEEN 1 AND (2 AND NULL), (3 BETWEEN 1 AND 2) AND NULL;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 3 between 1 and 2 and NULL AS `3 BETWEEN 1 AND 2 AND NULL`,3 between (1 and 2) and NULL AS `3 BETWEEN (1 AND 2) AND NULL`,3 between 1 and (2 and NULL) AS `3 BETWEEN 1 AND (2 AND NULL)`,3 between 1 and 2 and NULL AS `(3 BETWEEN 1 AND 2) AND NULL`
+select 3 BETWEEN 1 AND 2 AND NULL, 3 BETWEEN (1 AND 2) AND NULL, 3 BETWEEN 1 AND (2 AND NULL), (3 BETWEEN 1 AND 2) AND NULL union select * from v1;
+3 BETWEEN 1 AND 2 AND NULL 3 BETWEEN (1 AND 2) AND NULL 3 BETWEEN 1 AND (2 AND NULL) (3 BETWEEN 1 AND 2) AND NULL
+0 NULL NULL 0
+set sql_mode=PIPES_AS_CONCAT;
+create or replace view v1 as select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 or concat(3,3) AS `2 OR 3 || 3`,2 or concat(3,3) AS `2 OR (3 || 3)`,concat(2 or 3,3) AS `(2 OR 3) || 3`
+select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3 union select * from v1;
+2 OR 3 || 3 2 OR (3 || 3) (2 OR 3) || 3
+1 1 13
+create or replace view v1 as select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) or 3 AS `2 || 3 OR 3`,concat(2,3 or 3) AS `2 || (3 OR 3)`,concat(2,3) or 3 AS `(2 || 3) OR 3`
+select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3 union select * from v1;
+2 || 3 OR 3 2 || (3 OR 3) (2 || 3) OR 3
+1 21 1
+create or replace view v1 as select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !concat(2,3) AS `NOT 2 || 3`,!concat(2,3) AS `NOT (2 || 3)`,concat(!2,3) AS `(NOT 2) || 3`
+select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3 union select * from v1;
+NOT 2 || 3 NOT (2 || 3) (NOT 2) || 3
+0 0 03
+create or replace view v1 as select - '2 ' || 3, - ('2 ' || 3), (- '2 ') || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(-'2 ',3) AS `- '2 ' || 3`,-concat('2 ',3) AS `- ('2 ' || 3)`,concat(-'2 ',3) AS `(- '2 ') || 3`
+select - '2 ' || 3, - ('2 ' || 3), (- '2 ') || 3 union select * from v1;
+- '2 ' || 3 - ('2 ' || 3) (- '2 ') || 3
+-23 -2 -23
+create or replace view v1 as select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(~2,3) AS `~ 2 || 3`,~concat(2,3) AS `~ (2 || 3)`,concat(~2,3) AS `(~ 2) || 3`
+select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3 union select * from v1;
+~ 2 || 3 ~ (2 || 3) (~ 2) || 3
+184467440737095516133 18446744073709551592 184467440737095516133
+create or replace view v1 as select ! 2 || 3, ! (2 || 3), (! 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(!2,3) AS `! 2 || 3`,!concat(2,3) AS `! (2 || 3)`,concat(!2,3) AS `(! 2) || 3`
+select ! 2 || 3, ! (2 || 3), (! 2) || 3 union select * from v1;
+! 2 || 3 ! (2 || 3) (! 2) || 3
+03 0 03
+create or replace view v1 as select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) is false AS `2 || 3 IS FALSE`,concat(2,3 is false) AS `2 || (3 IS FALSE)`,concat(2,3) is false AS `(2 || 3) IS FALSE`
+select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE union select * from v1;
+2 || 3 IS FALSE 2 || (3 IS FALSE) (2 || 3) IS FALSE
+0 20 0
+create or replace view v1 as select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,3) in (3,10) AS `0 || 3 IN (3,10)`,concat(0,3 in (3,10)) AS `0 || (3 IN (3,10))`,concat(0,3) in (3,10) AS `(0 || 3) IN (3,10)`
+select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10) union select * from v1;
+0 || 3 IN (3,10) 0 || (3 IN (3,10)) (0 || 3) IN (3,10)
+1 01 1
+create or replace view v1 as select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(1,0) xor 1 AS `1 || 0 XOR 1`,concat(1,0 xor 1) AS `1 || (0 XOR 1)`,concat(1,0) xor 1 AS `(1 || 0) XOR 1`
+select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1 union select * from v1;
+1 || 0 XOR 1 1 || (0 XOR 1) (1 || 0) XOR 1
+0 11 0
+create or replace view v1 as select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(1,1) and 0 AS `1 || 1 AND 0`,concat(1,1 and 0) AS `1 || (1 AND 0)`,concat(1,1) and 0 AS `(1 || 1) AND 0`
+select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0 union select * from v1;
+1 || 1 AND 0 1 || (1 AND 0) (1 || 1) AND 0
+0 10 0
+create or replace view v1 as select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(1,1) and 0 AS `1 || 1 && 0`,concat(1,1 and 0) AS `1 || (1 && 0)`,concat(1,1) and 0 AS `(1 || 1) && 0`
+select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0 union select * from v1;
+1 || 1 && 0 1 || (1 && 0) (1 || 1) && 0
+0 10 0
+create or replace view v1 as select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) = 3 AS `2 || 3 = 3`,concat(2,3 = 3) AS `2 || (3 = 3)`,concat(2,3) = 3 AS `(2 || 3) = 3`
+select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3 union select * from v1;
+2 || 3 = 3 2 || (3 = 3) (2 || 3) = 3
+0 21 0
+create or replace view v1 as select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) <=> 3 AS `2 || 3 <=> 3`,concat(2,3 <=> 3) AS `2 || (3 <=> 3)`,concat(2,3) <=> 3 AS `(2 || 3) <=> 3`
+select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3 union select * from v1;
+2 || 3 <=> 3 2 || (3 <=> 3) (2 || 3) <=> 3
+0 21 0
+create or replace view v1 as select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) >= 3 AS `2 || 3 >= 3`,concat(2,3 >= 3) AS `2 || (3 >= 3)`,concat(2,3) >= 3 AS `(2 || 3) >= 3`
+select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3 union select * from v1;
+2 || 3 >= 3 2 || (3 >= 3) (2 || 3) >= 3
+1 21 1
+create or replace view v1 as select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) <= 0 AS `2 || 3 <= 0`,concat(2,3 <= 0) AS `2 || (3 <= 0)`,concat(2,3) <= 0 AS `(2 || 3) <= 0`
+select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0 union select * from v1;
+2 || 3 <= 0 2 || (3 <= 0) (2 || 3) <= 0
+0 20 0
+create or replace view v1 as select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) < 0 AS `2 || 3 < 0`,concat(2,3 < 0) AS `2 || (3 < 0)`,concat(2,3) < 0 AS `(2 || 3) < 0`
+select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0 union select * from v1;
+2 || 3 < 0 2 || (3 < 0) (2 || 3) < 0
+0 20 0
+create or replace view v1 as select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,3) <> 3 AS `0 || 3 <> 3`,concat(0,3 <> 3) AS `0 || (3 <> 3)`,concat(0,3) <> 3 AS `(0 || 3) <> 3`
+select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3 union select * from v1;
+0 || 3 <> 3 0 || (3 <> 3) (0 || 3) <> 3
+0 00 0
+create or replace view v1 as select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) > 3 AS `2 || 3 > 3`,concat(2,3 > 3) AS `2 || (3 > 3)`,concat(2,3) > 3 AS `(2 || 3) > 3`
+select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3 union select * from v1;
+2 || 3 > 3 2 || (3 > 3) (2 || 3) > 3
+1 20 1
+create or replace view v1 as select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,3) <> 3 AS `0 || 3 != 3`,concat(0,3 <> 3) AS `0 || (3 != 3)`,concat(0,3) <> 3 AS `(0 || 3) != 3`
+select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3 union select * from v1;
+0 || 3 != 3 0 || (3 != 3) (0 || 3) != 3
+0 00 0
+create or replace view v1 as select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) like 3 AS `2 || 3 LIKE 3`,concat(2,3 like 3) AS `2 || (3 LIKE 3)`,concat(2,3) like 3 AS `(2 || 3) LIKE 3`
+select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3 union select * from v1;
+2 || 3 LIKE 3 2 || (3 LIKE 3) (2 || 3) LIKE 3
+0 21 0
+create or replace view v1 as select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) regexp 3 AS `2 || 3 REGEXP 3`,concat(2,3 regexp 3) AS `2 || (3 REGEXP 3)`,concat(2,3) regexp 3 AS `(2 || 3) REGEXP 3`
+select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3 union select * from v1;
+2 || 3 REGEXP 3 2 || (3 REGEXP 3) (2 || 3) REGEXP 3
+1 21 1
+create or replace view v1 as select 2 || ' 3' | 3, 2 || (' 3' | 3), (2 || ' 3') | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,' 3') | 3 AS `2 || ' 3' | 3`,concat(2,' 3' | 3) AS `2 || (' 3' | 3)`,concat(2,' 3') | 3 AS `(2 || ' 3') | 3`
+select 2 || ' 3' | 3, 2 || (' 3' | 3), (2 || ' 3') | 3 union select * from v1;
+2 || ' 3' | 3 2 || (' 3' | 3) (2 || ' 3') | 3
+3 23 3
+create or replace view v1 as select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,2) & 2 AS `0 || 2 & 2`,concat(0,2 & 2) AS `0 || (2 & 2)`,concat(0,2) & 2 AS `(0 || 2) & 2`
+select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2 union select * from v1;
+0 || 2 & 2 0 || (2 & 2) (0 || 2) & 2
+2 02 2
+create or replace view v1 as select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) << 3 AS `2 || 3 << 3`,concat(2,3 << 3) AS `2 || (3 << 3)`,concat(2,3) << 3 AS `(2 || 3) << 3`
+select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3 union select * from v1;
+2 || 3 << 3 2 || (3 << 3) (2 || 3) << 3
+184 224 184
+create or replace view v1 as select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) >> 3 AS `2 || 3 >> 3`,concat(2,3 >> 3) AS `2 || (3 >> 3)`,concat(2,3) >> 3 AS `(2 || 3) >> 3`
+select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3 union select * from v1;
+2 || 3 >> 3 2 || (3 >> 3) (2 || 3) >> 3
+2 20 2
+create or replace view v1 as select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,'2000-01-01') + interval 1 day AS `2 || '2000-01-01' +INTERVAL 1 DAY`,concat(2,'2000-01-01' + interval 1 day) AS `2 || ('2000-01-01' +INTERVAL 1 DAY)`,concat(2,'2000-01-01') + interval 1 day AS `(2 || '2000-01-01') +INTERVAL 1 DAY`
+select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+2 || '2000-01-01' +INTERVAL 1 DAY 2 || ('2000-01-01' +INTERVAL 1 DAY) (2 || '2000-01-01') +INTERVAL 1 DAY
+NULL 22000-01-02 NULL
+create or replace view v1 as select 2 || ' 3' + 3, 2 || (' 3' + 3), (2 || ' 3') + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,' 3') + 3 AS `2 || ' 3' + 3`,concat(2,' 3' + 3) AS `2 || (' 3' + 3)`,concat(2,' 3') + 3 AS `(2 || ' 3') + 3`
+select 2 || ' 3' + 3, 2 || (' 3' + 3), (2 || ' 3') + 3 union select * from v1;
+2 || ' 3' + 3 2 || (' 3' + 3) (2 || ' 3') + 3
+5 26 5
+create or replace view v1 as select 2 || ' 3' - 3, 2 || (' 3' - 3), (2 || ' 3') - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,' 3') - 3 AS `2 || ' 3' - 3`,concat(2,' 3' - 3) AS `2 || (' 3' - 3)`,concat(2,' 3') - 3 AS `(2 || ' 3') - 3`
+select 2 || ' 3' - 3, 2 || (' 3' - 3), (2 || ' 3') - 3 union select * from v1;
+2 || ' 3' - 3 2 || (' 3' - 3) (2 || ' 3') - 3
+-1 20 -1
+create or replace view v1 as select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) * 3 AS `2 || 3 * 3`,concat(2,3 * 3) AS `2 || (3 * 3)`,concat(2,3) * 3 AS `(2 || 3) * 3`
+select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3 union select * from v1;
+2 || 3 * 3 2 || (3 * 3) (2 || 3) * 3
+69 29 69
+create or replace view v1 as select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) / 3 AS `2 || 3 / 3`,concat(2,3 / 3) AS `2 || (3 / 3)`,concat(2,3) / 3 AS `(2 || 3) / 3`
+select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3 union select * from v1;
+2 || 3 / 3 2 || (3 / 3) (2 || 3) / 3
+7.666666666666667 21.0000 7.666666666666667
+create or replace view v1 as select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) DIV 3 AS `2 || 3 DIV 3`,concat(2,3 DIV 3) AS `2 || (3 DIV 3)`,concat(2,3) DIV 3 AS `(2 || 3) DIV 3`
+select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3 union select * from v1;
+2 || 3 DIV 3 2 || (3 DIV 3) (2 || 3) DIV 3
+7 21 7
+create or replace view v1 as select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,3) MOD 3 AS `0 || 3 MOD 3`,concat(0,3 MOD 3) AS `0 || (3 MOD 3)`,concat(0,3) MOD 3 AS `(0 || 3) MOD 3`
+select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3 union select * from v1;
+0 || 3 MOD 3 0 || (3 MOD 3) (0 || 3) MOD 3
+0 00 0
+create or replace view v1 as select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(0,3) MOD 3 AS `0 || 3 % 3`,concat(0,3 MOD 3) AS `0 || (3 % 3)`,concat(0,3) MOD 3 AS `(0 || 3) % 3`
+select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3 union select * from v1;
+0 || 3 % 3 0 || (3 % 3) (0 || 3) % 3
+0 00 0
+create or replace view v1 as select 2 || ' 3' ^ 3, 2 || (' 3' ^ 3), (2 || ' 3') ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,' 3') ^ 3 AS `2 || ' 3' ^ 3`,concat(2,' 3' ^ 3) AS `2 || (' 3' ^ 3)`,concat(2,' 3') ^ 3 AS `(2 || ' 3') ^ 3`
+select 2 || ' 3' ^ 3, 2 || (' 3' ^ 3), (2 || ' 3') ^ 3 union select * from v1;
+2 || ' 3' ^ 3 2 || (' 3' ^ 3) (2 || ' 3') ^ 3
+1 20 1
+create or replace view v1 as select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select concat(2,3) between 2 and 3 AS `2 || 3 BETWEEN 2 AND 3`,concat(2,3 between 2 and 3) AS `2 || (3 BETWEEN 2 AND 3)`,concat(2,3) between 2 and 3 AS `(2 || 3) BETWEEN 2 AND 3`
+select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3 union select * from v1;
+2 || 3 BETWEEN 2 AND 3 2 || (3 BETWEEN 2 AND 3) (2 || 3) BETWEEN 2 AND 3
+0 21 0
+create or replace view v1 as select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 xor concat(3,3) AS `2 XOR 3 || 3`,2 xor concat(3,3) AS `2 XOR (3 || 3)`,concat(2 xor 3,3) AS `(2 XOR 3) || 3`
+select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3 union select * from v1;
+2 XOR 3 || 3 2 XOR (3 || 3) (2 XOR 3) || 3
+0 0 03
+create or replace view v1 as select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and concat(3,3) AS `0 AND 3 || 3`,0 and concat(3,3) AS `0 AND (3 || 3)`,concat(0 and 3,3) AS `(0 AND 3) || 3`
+select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3 union select * from v1;
+0 AND 3 || 3 0 AND (3 || 3) (0 AND 3) || 3
+0 0 03
+create or replace view v1 as select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 and concat(3,3) AS `0 && 3 || 3`,0 and concat(3,3) AS `0 && (3 || 3)`,concat(0 and 3,3) AS `(0 && 3) || 3`
+select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3 union select * from v1;
+0 && 3 || 3 0 && (3 || 3) (0 && 3) || 3
+0 0 03
+create or replace view v1 as select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 = concat(3,3) AS `2 = 3 || 3`,2 = concat(3,3) AS `2 = (3 || 3)`,concat(2 = 3,3) AS `(2 = 3) || 3`
+select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3 union select * from v1;
+2 = 3 || 3 2 = (3 || 3) (2 = 3) || 3
+0 0 03
+create or replace view v1 as select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <=> concat(3,3) AS `2 <=> 3 || 3`,2 <=> concat(3,3) AS `2 <=> (3 || 3)`,concat(2 <=> 3,3) AS `(2 <=> 3) || 3`
+select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3 union select * from v1;
+2 <=> 3 || 3 2 <=> (3 || 3) (2 <=> 3) || 3
+0 0 03
+create or replace view v1 as select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >= concat(3,0) AS `2 >= 3 || 0`,2 >= concat(3,0) AS `2 >= (3 || 0)`,concat(2 >= 3,0) AS `(2 >= 3) || 0`
+select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0 union select * from v1;
+2 >= 3 || 0 2 >= (3 || 0) (2 >= 3) || 0
+0 0 00
+create or replace view v1 as select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 <= concat(3,3) AS `2 <= 3 || 3`,2 <= concat(3,3) AS `2 <= (3 || 3)`,concat(2 <= 3,3) AS `(2 <= 3) || 3`
+select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3 union select * from v1;
+2 <= 3 || 3 2 <= (3 || 3) (2 <= 3) || 3
+1 1 13
+create or replace view v1 as select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 < concat(3,3) AS `2 < 3 || 3`,2 < concat(3,3) AS `2 < (3 || 3)`,concat(2 < 3,3) AS `(2 < 3) || 3`
+select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3 union select * from v1;
+2 < 3 || 3 2 < (3 || 3) (2 < 3) || 3
+1 1 13
+create or replace view v1 as select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> concat(3,3) AS `1 <> 3 || 3`,1 <> concat(3,3) AS `1 <> (3 || 3)`,concat(1 <> 3,3) AS `(1 <> 3) || 3`
+select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3 union select * from v1;
+1 <> 3 || 3 1 <> (3 || 3) (1 <> 3) || 3
+1 1 13
+create or replace view v1 as select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 0 > concat(3,3) AS `0 > 3 || 3`,0 > concat(3,3) AS `0 > (3 || 3)`,concat(0 > 3,3) AS `(0 > 3) || 3`
+select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3 union select * from v1;
+0 > 3 || 3 0 > (3 || 3) (0 > 3) || 3
+0 0 03
+create or replace view v1 as select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> concat(3,3) AS `1 != 3 || 3`,1 <> concat(3,3) AS `1 != (3 || 3)`,concat(1 <> 3,3) AS `(1 != 3) || 3`
+select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3 union select * from v1;
+1 != 3 || 3 1 != (3 || 3) (1 != 3) || 3
+1 1 13
+create or replace view v1 as select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 like concat(3,3) AS `2 LIKE 3 || 3`,2 like concat(3,3) AS `2 LIKE (3 || 3)`,concat(2 like 3,3) AS `(2 LIKE 3) || 3`
+select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3 union select * from v1;
+2 LIKE 3 || 3 2 LIKE (3 || 3) (2 LIKE 3) || 3
+0 0 03
+create or replace view v1 as select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 regexp concat(3,3) AS `2 REGEXP 3 || 3`,2 regexp concat(3,3) AS `2 REGEXP (3 || 3)`,concat(2 regexp 3,3) AS `(2 REGEXP 3) || 3`
+select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3 union select * from v1;
+2 REGEXP 3 || 3 2 REGEXP (3 || 3) (2 REGEXP 3) || 3
+0 0 03
+create or replace view v1 as select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 | concat(3,3) AS `2 | 3 || 3`,2 | concat(3,3) AS `2 | (3 || 3)`,concat(2 | 3,3) AS `(2 | 3) || 3`
+select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3 union select * from v1;
+2 | 3 || 3 2 | (3 || 3) (2 | 3) || 3
+35 35 33
+create or replace view v1 as select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 & concat(3,3) AS `2 & 3 || 3`,2 & concat(3,3) AS `2 & (3 || 3)`,concat(2 & 3,3) AS `(2 & 3) || 3`
+select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3 union select * from v1;
+2 & 3 || 3 2 & (3 || 3) (2 & 3) || 3
+0 0 23
+create or replace view v1 as select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 << concat(3,3) AS `2 << 3 || 3`,2 << concat(3,3) AS `2 << (3 || 3)`,concat(2 << 3,3) AS `(2 << 3) || 3`
+select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3 union select * from v1;
+2 << 3 || 3 2 << (3 || 3) (2 << 3) || 3
+17179869184 17179869184 163
+create or replace view v1 as select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 >> concat(3,0) AS `2 >> 3 || 0`,2 >> concat(3,0) AS `2 >> (3 || 0)`,concat(2 >> 3,0) AS `(2 >> 3) || 0`
+select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0 union select * from v1;
+2 >> 3 || 0 2 >> (3 || 0) (2 >> 3) || 0
+0 0 00
+create or replace view v1 as select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 + concat(3,3) AS `2 + 3 || 3`,2 + concat(3,3) AS `2 + (3 || 3)`,concat(2 + 3,3) AS `(2 + 3) || 3`
+select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3 union select * from v1;
+2 + 3 || 3 2 + (3 || 3) (2 + 3) || 3
+35 35 53
+create or replace view v1 as select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 - concat(2,0) AS `2 - 2 || 0`,2 - concat(2,0) AS `2 - (2 || 0)`,concat(2 - 2,0) AS `(2 - 2) || 0`
+select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0 union select * from v1;
+2 - 2 || 0 2 - (2 || 0) (2 - 2) || 0
+-18 -18 00
+create or replace view v1 as select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 * concat(3,3) AS `2 * 3 || 3`,2 * concat(3,3) AS `2 * (3 || 3)`,concat(2 * 3,3) AS `(2 * 3) || 3`
+select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3 union select * from v1;
+2 * 3 || 3 2 * (3 || 3) (2 * 3) || 3
+66 66 63
+create or replace view v1 as select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 / concat(3,3) AS `2 / 3 || 3`,2 / concat(3,3) AS `2 / (3 || 3)`,concat(2 / 3,3) AS `(2 / 3) || 3`
+select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3 union select * from v1;
+2 / 3 || 3 2 / (3 || 3) (2 / 3) || 3
+0.06060606060606061 0.06060606060606061 0.66673
+create or replace view v1 as select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 DIV concat(3,3) AS `2 DIV 3 || 3`,2 DIV concat(3,3) AS `2 DIV (3 || 3)`,concat(2 DIV 3,3) AS `(2 DIV 3) || 3`
+select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3 union select * from v1;
+2 DIV 3 || 3 2 DIV (3 || 3) (2 DIV 3) || 3
+0 0 03
+create or replace view v1 as select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD concat(3,3) AS `2 MOD 3 || 3`,2 MOD concat(3,3) AS `2 MOD (3 || 3)`,concat(2 MOD 3,3) AS `(2 MOD 3) || 3`
+select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3 union select * from v1;
+2 MOD 3 || 3 2 MOD (3 || 3) (2 MOD 3) || 3
+2 2 23
+create or replace view v1 as select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 MOD concat(3,3) AS `2 % 3 || 3`,2 MOD concat(3,3) AS `2 % (3 || 3)`,concat(2 MOD 3,3) AS `(2 % 3) || 3`
+select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3 union select * from v1;
+2 % 3 || 3 2 % (3 || 3) (2 % 3) || 3
+2 2 23
+create or replace view v1 as select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 ^ concat(3,3) AS `2 ^ 3 || 3`,2 ^ concat(3,3) AS `2 ^ (3 || 3)`,concat(2 ^ 3,3) AS `(2 ^ 3) || 3`
+select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3 union select * from v1;
+2 ^ 3 || 3 2 ^ (3 || 3) (2 ^ 3) || 3
+35 35 13
+create or replace view v1 as select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 2 between 1 and concat(3,3) AS `2 BETWEEN 1 AND 3 || 3`,2 between 1 and concat(3,3) AS `2 BETWEEN 1 AND (3 || 3)`,concat(2 between 1 and 3,3) AS `(2 BETWEEN 1 AND 3) || 3`
+select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3 union select * from v1;
+2 BETWEEN 1 AND 3 || 3 2 BETWEEN 1 AND (3 || 3) (2 BETWEEN 1 AND 3) || 3
+1 1 13
+create or replace view v1 as select charset(2 LIKE 1 ESCAPE 3 || ''), charset(2 LIKE 1 ESCAPE (3 || '')), charset((2 LIKE 1 ESCAPE 3) || '');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select charset(2 like 1 escape concat(3,'')) AS `charset(2 LIKE 1 ESCAPE 3 || '')`,charset(2 like 1 escape concat(3,'')) AS `charset(2 LIKE 1 ESCAPE (3 || ''))`,charset(concat(2 like 1 escape 3,'')) AS `charset((2 LIKE 1 ESCAPE 3) || '')`
+select charset(2 LIKE 1 ESCAPE 3 || ''), charset(2 LIKE 1 ESCAPE (3 || '')), charset((2 LIKE 1 ESCAPE 3) || '') union select * from v1;
+charset(2 LIKE 1 ESCAPE 3 || '') charset(2 LIKE 1 ESCAPE (3 || '')) charset((2 LIKE 1 ESCAPE 3) || '')
+binary binary latin1
+create or replace view v1 as select ! - 1, - ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !-1 AS `! - 1`,-!1 AS `- ! 1`
+create or replace view v1 as select ! BINARY 1, BINARY ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !cast(1 as char charset binary) AS `! BINARY 1`,cast(!1 as char charset binary) AS `BINARY ! 1`
+create or replace view v1 as select ! (NOT 1), NOT ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 <> 0 AS `! (NOT 1)`,1 <> 0 AS `NOT ! 1`
+create or replace view v1 as select ! ~ 1, ~ ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !~1 AS `! ~ 1`,~!1 AS `~ ! 1`
+create or replace view v1 as select - BINARY 1, BINARY - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -cast(1 as char charset binary) AS `- BINARY 1`,cast(-1 as char charset binary) AS `BINARY - 1`
+create or replace view v1 as select - (NOT 1), NOT - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -!1 AS `- (NOT 1)`,!-1 AS `NOT - 1`
+create or replace view v1 as select - ~ 1, ~ - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select -~1 AS `- ~ 1`,~-1 AS `~ - 1`
+create or replace view v1 as select BINARY (NOT 1), NOT BINARY 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast(!1 as char charset binary) AS `BINARY (NOT 1)`,!cast(1 as char charset binary) AS `NOT BINARY 1`
+create or replace view v1 as select BINARY ~ 1, ~ BINARY 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select cast(~1 as char charset binary) AS `BINARY ~ 1`,~cast(1 as char charset binary) AS `~ BINARY 1`
+create or replace view v1 as select NOT ~ 1, ~ (NOT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select !~1 AS `NOT ~ 1`,~!1 AS `~ (NOT 1)`
+create or replace view v1 as select 1 IS TRUE IS FALSE, 2 IS FALSE IS UNKNOWN, 3 IS UNKNOWN IS NULL, 4 IS NULL IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+view_definition
+select 1 is true is false AS `1 IS TRUE IS FALSE`,/*always not null*/ 1 is null AS `2 IS FALSE IS UNKNOWN`,/*always not null*/ 1 is null AS `3 IS UNKNOWN IS NULL`,/*always not null*/ 1 is null is true AS `4 IS NULL IS TRUE`
+drop view v1;
diff --git a/mysql-test/main/precedence.test b/mysql-test/main/precedence.test
new file mode 100644
index 00000000000..ad367c23603
--- /dev/null
+++ b/mysql-test/main/precedence.test
@@ -0,0 +1,4788 @@
+#
+# A fairly exhastive test for operator precedence
+#
+
+disable_warnings;
+
+#################### I couldn't come up with a test where precedence changes the result here
+#
+#create or replace view v1 as select BINARY 2 IS TRUE, BINARY (2 IS TRUE), (BINARY 2) IS TRUE;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 IS TRUE, BINARY (2 IS TRUE), (BINARY 2) IS TRUE union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 OR 3, BINARY (2 OR 3), (BINARY 2) OR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 OR 3, BINARY (2 OR 3), (BINARY 2) OR 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 || 3, BINARY (2 || 3), (BINARY 2) || 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 || 3, BINARY (2 || 3), (BINARY 2) || 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 XOR 3, BINARY (2 XOR 3), (BINARY 2) XOR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 XOR 3, BINARY (2 XOR 3), (BINARY 2) XOR 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 AND 3, BINARY (2 AND 3), (BINARY 2) AND 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 AND 3, BINARY (2 AND 3), (BINARY 2) AND 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 && 3, BINARY (2 && 3), (BINARY 2) && 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 && 3, BINARY (2 && 3), (BINARY 2) && 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 | 3, BINARY (2 | 3), (BINARY 2) | 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 | 3, BINARY (2 | 3), (BINARY 2) | 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 & 3, BINARY (2 & 3), (BINARY 2) & 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 & 3, BINARY (2 & 3), (BINARY 2) & 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 << 3, BINARY (2 << 3), (BINARY 2) << 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 << 3, BINARY (2 << 3), (BINARY 2) << 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 >> 3, BINARY (2 >> 3), (BINARY 2) >> 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 >> 3, BINARY (2 >> 3), (BINARY 2) >> 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY '2000-01-01' +INTERVAL 1 DAY, BINARY ('2000-01-01' +INTERVAL 1 DAY), (BINARY '2000-01-01') +INTERVAL 1 DAY;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY '2000-01-01' +INTERVAL 1 DAY, BINARY ('2000-01-01' +INTERVAL 1 DAY), (BINARY '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 + 3, BINARY (2 + 3), (BINARY 2) + 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 + 3, BINARY (2 + 3), (BINARY 2) + 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 - 3, BINARY (2 - 3), (BINARY 2) - 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 - 3, BINARY (2 - 3), (BINARY 2) - 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 * 3, BINARY (2 * 3), (BINARY 2) * 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 * 3, BINARY (2 * 3), (BINARY 2) * 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 / 3, BINARY (2 / 3), (BINARY 2) / 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 / 3, BINARY (2 / 3), (BINARY 2) / 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 DIV 3, BINARY (2 DIV 3), (BINARY 2) DIV 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 DIV 3, BINARY (2 DIV 3), (BINARY 2) DIV 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 MOD 3, BINARY (2 MOD 3), (BINARY 2) MOD 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 MOD 3, BINARY (2 MOD 3), (BINARY 2) MOD 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 % 3, BINARY (2 % 3), (BINARY 2) % 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 % 3, BINARY (2 % 3), (BINARY 2) % 3 union select * from v1;
+#
+#create or replace view v1 as select BINARY 2 ^ 3, BINARY (2 ^ 3), (BINARY 2) ^ 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select BINARY 2 ^ 3, BINARY (2 ^ 3), (BINARY 2) ^ 3 union select * from v1;
+#
+#set sql_mode=PIPES_AS_CONCAT;
+#create or replace view v1 as select 2 || 3 COLLATE latin1_bin, 2 || (3 COLLATE latin1_bin), (2 || 3) COLLATE latin1_bin;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 || 3 COLLATE latin1_bin, 2 || (3 COLLATE latin1_bin), (2 || 3) COLLATE latin1_bin union select * from v1;
+
+########################## The result doesn't depend on the precedence
+#
+#create or replace view v1 as select NOT 2 XOR 0, NOT (2 XOR 0), (NOT 2) XOR 0;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select NOT 2 XOR 0, NOT (2 XOR 0), (NOT 2) XOR 0 union select * from v1;
+#
+#create or replace view v1 as select - 2 * 3, - (2 * 3), (- 2) * 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select - 2 * 3, - (2 * 3), (- 2) * 3 union select * from v1;
+#
+#create or replace view v1 as select - 2 / 3, - (2 / 3), (- 2) / 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select - 2 / 3, - (2 / 3), (- 2) / 3 union select * from v1;
+#
+#create or replace view v1 as select - 2 DIV 3, - (2 DIV 3), (- 2) DIV 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select - 2 DIV 3, - (2 DIV 3), (- 2) DIV 3 union select * from v1;
+#
+#create or replace view v1 as select - 2 MOD 3, - (2 MOD 3), (- 2) MOD 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select - 2 MOD 3, - (2 MOD 3), (- 2) MOD 3 union select * from v1;
+#
+#create or replace view v1 as select - 2 % 3, - (2 % 3), (- 2) % 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select - 2 % 3, - (2 % 3), (- 2) % 3 union select * from v1;
+#
+#create or replace view v1 as select ~ 2 ^ 3, ~ (2 ^ 3), (~ 2) ^ 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select ~ 2 ^ 3, ~ (2 ^ 3), (~ 2) ^ 3 union select * from v1;
+#
+#create or replace view v1 as select ! 2 XOR 3, ! (2 XOR 3), (! 2) XOR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select ! 2 XOR 3, ! (2 XOR 3), (! 2) XOR 3 union select * from v1;
+#
+#create or replace view v1 as select 2 OR 3 OR 3, 2 OR (3 OR 3), (2 OR 3) OR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 OR 3 OR 3, 2 OR (3 OR 3), (2 OR 3) OR 3 union select * from v1;
+#
+#create or replace view v1 as select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3 union select * from v1;
+#
+#create or replace view v1 as select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3 union select * from v1;
+#
+#create or replace view v1 as select 2 || 3 || 3, 2 || (3 || 3), (2 || 3) || 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 || 3 || 3, 2 || (3 || 3), (2 || 3) || 3 union select * from v1;
+#
+#create or replace view v1 as select 2 XOR 3 IS FALSE, 2 XOR (3 IS FALSE), (2 XOR 3) IS FALSE;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 XOR 3 IS FALSE, 2 XOR (3 IS FALSE), (2 XOR 3) IS FALSE union select * from v1;
+#
+#create or replace view v1 as select 2 XOR 3 XOR 3, 2 XOR (3 XOR 3), (2 XOR 3) XOR 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 XOR 3 XOR 3, 2 XOR (3 XOR 3), (2 XOR 3) XOR 3 union select * from v1;
+#
+#create or replace view v1 as select 2 AND 3 AND 3, 2 AND (3 AND 3), (2 AND 3) AND 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 AND 3 AND 3, 2 AND (3 AND 3), (2 AND 3) AND 3 union select * from v1;
+#
+#create or replace view v1 as select 2 AND 3 && 3, 2 AND (3 && 3), (2 AND 3) && 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 AND 3 && 3, 2 AND (3 && 3), (2 AND 3) && 3 union select * from v1;
+#
+#create or replace view v1 as select 2 && 3 AND 3, 2 && (3 AND 3), (2 && 3) AND 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 && 3 AND 3, 2 && (3 AND 3), (2 && 3) AND 3 union select * from v1;
+#
+#create or replace view v1 as select 2 && 3 && 3, 2 && (3 && 3), (2 && 3) && 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 && 3 && 3, 2 && (3 && 3), (2 && 3) && 3 union select * from v1;
+#
+#create or replace view v1 as select 2 | 3 | 3, 2 | (3 | 3), (2 | 3) | 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 | 3 | 3, 2 | (3 | 3), (2 | 3) | 3 union select * from v1;
+#
+#create or replace view v1 as select 2 & 3 & 3, 2 & (3 & 3), (2 & 3) & 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 & 3 & 3, 2 & (3 & 3), (2 & 3) & 3 union select * from v1;
+#
+#create or replace view v1 as select 2 + 3 + 3, 2 + (3 + 3), (2 + 3) + 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 + 3 + 3, 2 + (3 + 3), (2 + 3) + 3 union select * from v1;
+#
+#create or replace view v1 as select 2 + 3 - 3, 2 + (3 - 3), (2 + 3) - 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 + 3 - 3, 2 + (3 - 3), (2 + 3) - 3 union select * from v1;
+#
+#create or replace view v1 as select 2 * 3 << 3, 2 * (3 << 3), (2 * 3) << 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 * 3 << 3, 2 * (3 << 3), (2 * 3) << 3 union select * from v1;
+#
+#create or replace view v1 as select 2 * 3 * 3, 2 * (3 * 3), (2 * 3) * 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 * 3 * 3, 2 * (3 * 3), (2 * 3) * 3 union select * from v1;
+#
+#create or replace view v1 as select 2 * 3 / 3, 2 * (3 / 3), (2 * 3) / 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 * 3 / 3, 2 * (3 / 3), (2 * 3) / 3 union select * from v1;
+#
+#create or replace view v1 as select 2 ^ 3 ^ 3, 2 ^ (3 ^ 3), (2 ^ 3) ^ 3;
+#Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+#select 2 ^ 3 ^ 3, 2 ^ (3 ^ 3), (2 ^ 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select NOT NULL IS TRUE, NOT (NULL IS TRUE), (NOT NULL) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT NULL IS TRUE, NOT (NULL IS TRUE), (NOT NULL) IS TRUE union select * from v1;
+
+create or replace view v1 as select ! NULL IS TRUE, ! (NULL IS TRUE), (! NULL) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! NULL IS TRUE, ! (NULL IS TRUE), (! NULL) IS TRUE union select * from v1;
+
+create or replace view v1 as select charset(NOT 2 COLLATE latin1_bin), charset(NOT (2 COLLATE latin1_bin)), charset((NOT 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(NOT 2 COLLATE latin1_bin), charset(NOT (2 COLLATE latin1_bin)), charset((NOT 2) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select NOT 2 IN (0,2), NOT (2 IN (0,2)), (NOT 2) IN (0,2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 IN (0,2), NOT (2 IN (0,2)), (NOT 2) IN (0,2) union select * from v1;
+
+create or replace view v1 as select NOT 2 OR 3, NOT (2 OR 3), (NOT 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 OR 3, NOT (2 OR 3), (NOT 2) OR 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 AND 0, NOT (2 AND 0), (NOT 2) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 AND 0, NOT (2 AND 0), (NOT 2) AND 0 union select * from v1;
+
+create or replace view v1 as select NOT 2 && 0, NOT (2 && 0), (NOT 2) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 && 0, NOT (2 && 0), (NOT 2) && 0 union select * from v1;
+
+create or replace view v1 as select NOT 2 = 3, NOT (2 = 3), (NOT 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 = 3, NOT (2 = 3), (NOT 2) = 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 <=> 3, NOT (2 <=> 3), (NOT 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 <=> 3, NOT (2 <=> 3), (NOT 2) <=> 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 >= 3, NOT (2 >= 3), (NOT 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 >= 3, NOT (2 >= 3), (NOT 2) >= 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 <= 3, NOT (2 <= 3), (NOT 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 <= 3, NOT (2 <= 3), (NOT 2) <= 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 < 3, NOT (2 < 3), (NOT 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 < 3, NOT (2 < 3), (NOT 2) < 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 <> 3, NOT (2 <> 3), (NOT 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 <> 3, NOT (2 <> 3), (NOT 2) <> 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 > 3, NOT (2 > 3), (NOT 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 > 3, NOT (2 > 3), (NOT 2) > 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 != 3, NOT (2 != 3), (NOT 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 != 3, NOT (2 != 3), (NOT 2) != 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 LIKE 3, NOT (2 LIKE 3), (NOT 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 LIKE 3, NOT (2 LIKE 3), (NOT 2) LIKE 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 REGEXP 3, NOT (2 REGEXP 3), (NOT 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 REGEXP 3, NOT (2 REGEXP 3), (NOT 2) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 | 3, NOT (2 | 3), (NOT 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 | 3, NOT (2 | 3), (NOT 2) | 3 union select * from v1;
+
+create or replace view v1 as select NOT 0 & 2, NOT (0 & 2), (NOT 0) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 0 & 2, NOT (0 & 2), (NOT 0) & 2 union select * from v1;
+
+create or replace view v1 as select NOT 0 << 3, NOT (0 << 3), (NOT 0) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 0 << 3, NOT (0 << 3), (NOT 0) << 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 >> 3, NOT (2 >> 3), (NOT 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 >> 3, NOT (2 >> 3), (NOT 2) >> 3 union select * from v1;
+
+create or replace view v1 as select NOT '2000-01-01' +INTERVAL 1 DAY, NOT ('2000-01-01' +INTERVAL 1 DAY), (NOT '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT '2000-01-01' +INTERVAL 1 DAY, NOT ('2000-01-01' +INTERVAL 1 DAY), (NOT '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select NOT 2 + 3, NOT (2 + 3), (NOT 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 + 3, NOT (2 + 3), (NOT 2) + 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 - 3, NOT (2 - 3), (NOT 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 - 3, NOT (2 - 3), (NOT 2) - 3 union select * from v1;
+
+create or replace view v1 as select NOT 0 * 3, NOT (0 * 3), (NOT 0) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 0 * 3, NOT (0 * 3), (NOT 0) * 3 union select * from v1;
+
+create or replace view v1 as select NOT 0 / 3, NOT (0 / 3), (NOT 0) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 0 / 3, NOT (0 / 3), (NOT 0) / 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 DIV 3, NOT (2 DIV 3), (NOT 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 DIV 3, NOT (2 DIV 3), (NOT 2) DIV 3 union select * from v1;
+
+create or replace view v1 as select NOT 6 MOD 3, NOT (6 MOD 3), (NOT 6) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 6 MOD 3, NOT (6 MOD 3), (NOT 6) MOD 3 union select * from v1;
+
+create or replace view v1 as select NOT 6 % 3, NOT (6 % 3), (NOT 6) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 6 % 3, NOT (6 % 3), (NOT 6) % 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 ^ 3, NOT (2 ^ 3), (NOT 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 ^ 3, NOT (2 ^ 3), (NOT 2) ^ 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 BETWEEN 3 AND 4, NOT (2 BETWEEN 3 AND 4), (NOT 2) BETWEEN 3 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 BETWEEN 3 AND 4, NOT (2 BETWEEN 3 AND 4), (NOT 2) BETWEEN 3 AND 4 union select * from v1;
+
+create or replace view v1 as select - 2 IS TRUE, - (2 IS TRUE), (- 2) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 IS TRUE, - (2 IS TRUE), (- 2) IS TRUE union select * from v1;
+
+create or replace view v1 as select charset(- "2" COLLATE latin1_bin), charset(- ("2" COLLATE latin1_bin)), charset((- "2") COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(- "2" COLLATE latin1_bin), charset(- ("2" COLLATE latin1_bin)), charset((- "2") COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select - 2 IN (2,1), - (2 IN (2,1)), (- 2) IN (2,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 IN (2,1), - (2 IN (2,1)), (- 2) IN (2,1) union select * from v1;
+
+create or replace view v1 as select - 2 OR 3, - (2 OR 3), (- 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 OR 3, - (2 OR 3), (- 2) OR 3 union select * from v1;
+
+create or replace view v1 as select - 2 || 3, - (2 || 3), (- 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 || 3, - (2 || 3), (- 2) || 3 union select * from v1;
+
+create or replace view v1 as select - 0 XOR 3, - (0 XOR 3), (- 0) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 0 XOR 3, - (0 XOR 3), (- 0) XOR 3 union select * from v1;
+
+create or replace view v1 as select - 2 AND 3, - (2 AND 3), (- 2) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 AND 3, - (2 AND 3), (- 2) AND 3 union select * from v1;
+
+create or replace view v1 as select - 2 && 3, - (2 && 3), (- 2) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 && 3, - (2 && 3), (- 2) && 3 union select * from v1;
+
+create or replace view v1 as select - 2 = 2, - (2 = 2), (- 2) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 = 2, - (2 = 2), (- 2) = 2 union select * from v1;
+
+create or replace view v1 as select - 2 <=> 2, - (2 <=> 2), (- 2) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 <=> 2, - (2 <=> 2), (- 2) <=> 2 union select * from v1;
+
+create or replace view v1 as select - 2 >= 1, - (2 >= 1), (- 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 >= 1, - (2 >= 1), (- 2) >= 1 union select * from v1;
+
+create or replace view v1 as select - 2 <= 3, - (2 <= 3), (- 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 <= 3, - (2 <= 3), (- 2) <= 3 union select * from v1;
+
+create or replace view v1 as select - 2 < 3, - (2 < 3), (- 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 < 3, - (2 < 3), (- 2) < 3 union select * from v1;
+
+create or replace view v1 as select - 2 <> 3, - (2 <> 3), (- 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 <> 3, - (2 <> 3), (- 2) <> 3 union select * from v1;
+
+create or replace view v1 as select - 2 > 1, - (2 > 1), (- 2) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 > 1, - (2 > 1), (- 2) > 1 union select * from v1;
+
+create or replace view v1 as select - 2 != 3, - (2 != 3), (- 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 != 3, - (2 != 3), (- 2) != 3 union select * from v1;
+
+create or replace view v1 as select - 2 LIKE 2, - (2 LIKE 2), (- 2) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 LIKE 2, - (2 LIKE 2), (- 2) LIKE 2 union select * from v1;
+
+create or replace view v1 as select - 2 REGEXP 2, - (2 REGEXP 2), (- 2) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 REGEXP 2, - (2 REGEXP 2), (- 2) REGEXP 2 union select * from v1;
+
+create or replace view v1 as select - 2 | 3, - (2 | 3), (- 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 | 3, - (2 | 3), (- 2) | 3 union select * from v1;
+
+create or replace view v1 as select - 2 & 3, - (2 & 3), (- 2) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 & 3, - (2 & 3), (- 2) & 3 union select * from v1;
+
+create or replace view v1 as select - 2 << 3, - (2 << 3), (- 2) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 << 3, - (2 << 3), (- 2) << 3 union select * from v1;
+
+create or replace view v1 as select - 2 >> 3, - (2 >> 3), (- 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 >> 3, - (2 >> 3), (- 2) >> 3 union select * from v1;
+
+create or replace view v1 as select - '2000-01-01' +INTERVAL 1 DAY, - ('2000-01-01' +INTERVAL 1 DAY), (- '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - '2000-01-01' +INTERVAL 1 DAY, - ('2000-01-01' +INTERVAL 1 DAY), (- '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select - 2 + 3, - (2 + 3), (- 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 + 3, - (2 + 3), (- 2) + 3 union select * from v1;
+
+create or replace view v1 as select - 2 - 3, - (2 - 3), (- 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 - 3, - (2 - 3), (- 2) - 3 union select * from v1;
+
+create or replace view v1 as select - 2 ^ 3, - (2 ^ 3), (- 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 ^ 3, - (2 ^ 3), (- 2) ^ 3 union select * from v1;
+
+create or replace view v1 as select - 2 BETWEEN 1 AND 3, - (2 BETWEEN 1 AND 3), (- 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 BETWEEN 1 AND 3, - (2 BETWEEN 1 AND 3), (- 2) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 IS TRUE, ~ (2 IS TRUE), (~ 2) IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 IS TRUE, ~ (2 IS TRUE), (~ 2) IS TRUE union select * from v1;
+
+create or replace view v1 as select charset(~ 2 COLLATE latin1_bin), charset(~ (2 COLLATE latin1_bin)), charset((~ 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(~ 2 COLLATE latin1_bin), charset(~ (2 COLLATE latin1_bin)), charset((~ 2) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select ~ 2 IN (0,1), ~ (2 IN (0,1)), (~ 2) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 IN (0,1), ~ (2 IN (0,1)), (~ 2) IN (0,1) union select * from v1;
+
+create or replace view v1 as select ~ 2 OR 3, ~ (2 OR 3), (~ 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 OR 3, ~ (2 OR 3), (~ 2) OR 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 XOR 3, ~ (2 XOR 3), (~ 2) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 XOR 3, ~ (2 XOR 3), (~ 2) XOR 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 AND 3, ~ (2 AND 3), (~ 2) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 AND 3, ~ (2 AND 3), (~ 2) AND 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 && 3, ~ (2 && 3), (~ 2) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 && 3, ~ (2 && 3), (~ 2) && 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 = 3, ~ (2 = 3), (~ 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 = 3, ~ (2 = 3), (~ 2) = 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 <=> 3, ~ (2 <=> 3), (~ 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 <=> 3, ~ (2 <=> 3), (~ 2) <=> 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 >= 3, ~ (2 >= 3), (~ 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 >= 3, ~ (2 >= 3), (~ 2) >= 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 <= 3, ~ (2 <= 3), (~ 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 <= 3, ~ (2 <= 3), (~ 2) <= 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 < 3, ~ (2 < 3), (~ 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 < 3, ~ (2 < 3), (~ 2) < 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 <> 3, ~ (2 <> 3), (~ 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 <> 3, ~ (2 <> 3), (~ 2) <> 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 > 3, ~ (2 > 3), (~ 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 > 3, ~ (2 > 3), (~ 2) > 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 != 3, ~ (2 != 3), (~ 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 != 3, ~ (2 != 3), (~ 2) != 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 LIKE 3, ~ (2 LIKE 3), (~ 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 LIKE 3, ~ (2 LIKE 3), (~ 2) LIKE 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 REGEXP 3, ~ (2 REGEXP 3), (~ 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 REGEXP 3, ~ (2 REGEXP 3), (~ 2) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 | 3, ~ (2 | 3), (~ 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 | 3, ~ (2 | 3), (~ 2) | 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 & 3, ~ (2 & 3), (~ 2) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 & 3, ~ (2 & 3), (~ 2) & 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 << 3, ~ (2 << 3), (~ 2) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 << 3, ~ (2 << 3), (~ 2) << 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 >> 3, ~ (2 >> 3), (~ 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 >> 3, ~ (2 >> 3), (~ 2) >> 3 union select * from v1;
+
+create or replace view v1 as select ~ '2000-01-01' +INTERVAL 1 DAY, ~ ('2000-01-01' +INTERVAL 1 DAY), (~ '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ '2000-01-01' +INTERVAL 1 DAY, ~ ('2000-01-01' +INTERVAL 1 DAY), (~ '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select ~ 10000 + 3, ~ (10000 + 3), (~ 10000) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 10000 + 3, ~ (10000 + 3), (~ 10000) + 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 - 3, ~ (2 - 3), (~ 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 - 3, ~ (2 - 3), (~ 2) - 3 union select * from v1;
+
+create or replace view v1 as select ~ 10000000000000000000 * 2, ~ (100 * 2), (~ 10000000000000000000) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 10000000000000000000 * 2, ~ (100 * 2), (~ 10000000000000000000) * 2 union select * from v1;
+
+create or replace view v1 as select ~ 2 / 3, ~ (2 / 3), (~ 2) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 / 3, ~ (2 / 3), (~ 2) / 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 DIV 3, ~ (2 DIV 3), (~ 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 DIV 3, ~ (2 DIV 3), (~ 2) DIV 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 MOD 3, ~ (2 MOD 3), (~ 2) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 MOD 3, ~ (2 MOD 3), (~ 2) MOD 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 % 3, ~ (2 % 3), (~ 2) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 % 3, ~ (2 % 3), (~ 2) % 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 BETWEEN 1 AND 3, ~ (2 BETWEEN 1 AND 3), (~ 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 BETWEEN 1 AND 3, ~ (2 BETWEEN 1 AND 3), (~ 2) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select charset(! 2 COLLATE latin1_bin), charset(! (2 COLLATE latin1_bin)), charset((! 2) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(! 2 COLLATE latin1_bin), charset(! (2 COLLATE latin1_bin)), charset((! 2) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select ! 2 IN (0,2), ! (2 IN (0,2)), (! 2) IN (0,2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 IN (0,2), ! (2 IN (0,2)), (! 2) IN (0,2) union select * from v1;
+
+create or replace view v1 as select ! 2 OR 3, ! (2 OR 3), (! 2) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 OR 3, ! (2 OR 3), (! 2) OR 3 union select * from v1;
+
+create or replace view v1 as select ! 2 || 3, ! (2 || 3), (! 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 || 3, ! (2 || 3), (! 2) || 3 union select * from v1;
+
+create or replace view v1 as select ! 2 AND 0, ! (2 AND 0), (! 2) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 AND 0, ! (2 AND 0), (! 2) AND 0 union select * from v1;
+
+create or replace view v1 as select ! 2 && 0, ! (2 && 0), (! 2) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 && 0, ! (2 && 0), (! 2) && 0 union select * from v1;
+
+create or replace view v1 as select ! 2 = 3, ! (2 = 3), (! 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 = 3, ! (2 = 3), (! 2) = 3 union select * from v1;
+
+create or replace view v1 as select ! 2 <=> 3, ! (2 <=> 3), (! 2) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 <=> 3, ! (2 <=> 3), (! 2) <=> 3 union select * from v1;
+
+create or replace view v1 as select ! 2 >= 3, ! (2 >= 3), (! 2) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 >= 3, ! (2 >= 3), (! 2) >= 3 union select * from v1;
+
+create or replace view v1 as select ! 2 <= 3, ! (2 <= 3), (! 2) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 <= 3, ! (2 <= 3), (! 2) <= 3 union select * from v1;
+
+create or replace view v1 as select ! 2 < 3, ! (2 < 3), (! 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 < 3, ! (2 < 3), (! 2) < 3 union select * from v1;
+
+create or replace view v1 as select ! 2 <> 3, ! (2 <> 3), (! 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 <> 3, ! (2 <> 3), (! 2) <> 3 union select * from v1;
+
+create or replace view v1 as select ! 2 > 3, ! (2 > 3), (! 2) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 > 3, ! (2 > 3), (! 2) > 3 union select * from v1;
+
+create or replace view v1 as select ! 2 != 3, ! (2 != 3), (! 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 != 3, ! (2 != 3), (! 2) != 3 union select * from v1;
+
+create or replace view v1 as select ! 2 LIKE 3, ! (2 LIKE 3), (! 2) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 LIKE 3, ! (2 LIKE 3), (! 2) LIKE 3 union select * from v1;
+
+create or replace view v1 as select ! 2 REGEXP 3, ! (2 REGEXP 3), (! 2) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 REGEXP 3, ! (2 REGEXP 3), (! 2) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select ! 2 | 3, ! (2 | 3), (! 2) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 | 3, ! (2 | 3), (! 2) | 3 union select * from v1;
+
+create or replace view v1 as select ! 2 & 0, ! (2 & 0), (! 2) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 & 0, ! (2 & 0), (! 2) & 0 union select * from v1;
+
+create or replace view v1 as select ! 0 << 3, ! (0 << 3), (! 0) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 0 << 3, ! (0 << 3), (! 0) << 3 union select * from v1;
+
+create or replace view v1 as select ! 2 >> 3, ! (2 >> 3), (! 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 >> 3, ! (2 >> 3), (! 2) >> 3 union select * from v1;
+
+create or replace view v1 as select ! '2000-01-01' +INTERVAL 1 DAY, ! ('2000-01-01' +INTERVAL 1 DAY), (! '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! '2000-01-01' +INTERVAL 1 DAY, ! ('2000-01-01' +INTERVAL 1 DAY), (! '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select ! 2 + 3, ! (2 + 3), (! 2) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 + 3, ! (2 + 3), (! 2) + 3 union select * from v1;
+
+create or replace view v1 as select ! 2 - 3, ! (2 - 3), (! 2) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 - 3, ! (2 - 3), (! 2) - 3 union select * from v1;
+
+create or replace view v1 as select ! 0 * 3, ! (0 * 3), (! 0) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 0 * 3, ! (0 * 3), (! 0) * 3 union select * from v1;
+
+create or replace view v1 as select ! 0 / 3, ! (0 / 3), (! 0) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 0 / 3, ! (0 / 3), (! 0) / 3 union select * from v1;
+
+create or replace view v1 as select ! 2 DIV 3, ! (2 DIV 3), (! 2) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 DIV 3, ! (2 DIV 3), (! 2) DIV 3 union select * from v1;
+
+create or replace view v1 as select ! 6 MOD 3, ! (6 MOD 3), (! 6) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 6 MOD 3, ! (6 MOD 3), (! 6) MOD 3 union select * from v1;
+
+create or replace view v1 as select ! 6 % 3, ! (6 % 3), (! 6) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 6 % 3, ! (6 % 3), (! 6) % 3 union select * from v1;
+
+create or replace view v1 as select ! 2 ^ 3, ! (2 ^ 3), (! 2) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 ^ 3, ! (2 ^ 3), (! 2) ^ 3 union select * from v1;
+
+create or replace view v1 as select ! 2 BETWEEN 3 AND 4, ! (2 BETWEEN 3 AND 4), (! 2) BETWEEN 3 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 BETWEEN 3 AND 4, ! (2 BETWEEN 3 AND 4), (! 2) BETWEEN 3 AND 4 union select * from v1;
+
+create or replace view v1 as select CHARSET(BINARY '2' COLLATE latin1_bin), CHARSET(BINARY ('2' COLLATE latin1_bin)), 'error'/*CHARSET((BINARY '2') COLLATE latin1_bin)*/;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select CHARSET(BINARY '2' COLLATE latin1_bin), CHARSET(BINARY ('2' COLLATE latin1_bin)), 'error'/*CHARSET((BINARY '2') COLLATE latin1_bin)*/ union select * from v1;
+
+create or replace view v1 as select BINARY 'c' IN ('C','X'), BINARY ('c' IN ('C','X')), (BINARY 'c') IN ('C','X');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' IN ('C','X'), BINARY ('c' IN ('C','X')), (BINARY 'c') IN ('C','X') union select * from v1;
+
+create or replace view v1 as select BINARY 'c' = 'C', BINARY ('c' = 'C'), (BINARY 'c') = 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' = 'C', BINARY ('c' = 'C'), (BINARY 'c') = 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' <=> 'C', BINARY ('c' <=> 'C'), (BINARY 'c') <=> 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' <=> 'C', BINARY ('c' <=> 'C'), (BINARY 'c') <=> 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' >= 'D', BINARY ('c' >= 'D'), (BINARY 'c') >= 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' >= 'D', BINARY ('c' >= 'D'), (BINARY 'c') >= 'D' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' <= 'C', BINARY ('c' <= 'C'), (BINARY 'c') <= 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' <= 'C', BINARY ('c' <= 'C'), (BINARY 'c') <= 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' < 'D', BINARY ('c' < 'D'), (BINARY 'c') < 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' < 'D', BINARY ('c' < 'D'), (BINARY 'c') < 'D' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' <> 'C', BINARY ('c' <> 'C'), (BINARY 'c') <> 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' <> 'C', BINARY ('c' <> 'C'), (BINARY 'c') <> 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' > 'C', BINARY ('c' > 'C'), (BINARY 'c') > 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' > 'C', BINARY ('c' > 'C'), (BINARY 'c') > 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' != 'C', BINARY ('c' != 'C'), (BINARY 'c') != 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' != 'C', BINARY ('c' != 'C'), (BINARY 'c') != 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' LIKE 'C', BINARY ('c' LIKE 'C'), (BINARY 'c') LIKE 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' LIKE 'C', BINARY ('c' LIKE 'C'), (BINARY 'c') LIKE 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' REGEXP 'C', BINARY ('c' REGEXP 'C'), (BINARY 'c') REGEXP 'C';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' REGEXP 'C', BINARY ('c' REGEXP 'C'), (BINARY 'c') REGEXP 'C' union select * from v1;
+
+create or replace view v1 as select BINARY 'c' BETWEEN 'A' AND 'D', BINARY ('c' BETWEEN 'A' AND 'D'), (BINARY 'c') BETWEEN 'A' AND 'D';
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' BETWEEN 'A' AND 'D', BINARY ('c' BETWEEN 'A' AND 'D'), (BINARY 'c') BETWEEN 'A' AND 'D' union select * from v1;
+
+create or replace view v1 as select 2 OR 3 IS FALSE, 2 OR (3 IS FALSE), (2 OR 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 IS FALSE, 2 OR (3 IS FALSE), (2 OR 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 OR 3 COLLATE latin1_bin), charset(2 OR (3 COLLATE latin1_bin)), charset((2 OR 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 OR 3 COLLATE latin1_bin), charset(2 OR (3 COLLATE latin1_bin)), charset((2 OR 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 0 OR 3 IN (3,10), 0 OR (3 IN (3,10)), (0 OR 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 IN (3,10), 0 OR (3 IN (3,10)), (0 OR 3) IN (3,10) union select * from v1;
+
+create or replace view v1 as select 1 OR 0 XOR 1, 1 OR (0 XOR 1), (1 OR 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 OR 0 XOR 1, 1 OR (0 XOR 1), (1 OR 0) XOR 1 union select * from v1;
+
+create or replace view v1 as select 1 OR 1 AND 0, 1 OR (1 AND 0), (1 OR 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 OR 1 AND 0, 1 OR (1 AND 0), (1 OR 1) AND 0 union select * from v1;
+
+create or replace view v1 as select 1 OR 1 && 0, 1 OR (1 && 0), (1 OR 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 OR 1 && 0, 1 OR (1 && 0), (1 OR 1) && 0 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 = 3, 2 OR (3 = 3), (2 OR 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 = 3, 2 OR (3 = 3), (2 OR 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 <=> 3, 2 OR (3 <=> 3), (2 OR 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 <=> 3, 2 OR (3 <=> 3), (2 OR 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 >= 3, 2 OR (3 >= 3), (2 OR 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 >= 3, 2 OR (3 >= 3), (2 OR 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 <= 0, 2 OR (3 <= 0), (2 OR 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 <= 0, 2 OR (3 <= 0), (2 OR 3) <= 0 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 < 0, 2 OR (3 < 0), (2 OR 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 < 0, 2 OR (3 < 0), (2 OR 3) < 0 union select * from v1;
+
+create or replace view v1 as select 0 OR 3 <> 3, 0 OR (3 <> 3), (0 OR 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 <> 3, 0 OR (3 <> 3), (0 OR 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 > 3, 2 OR (3 > 3), (2 OR 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 > 3, 2 OR (3 > 3), (2 OR 3) > 3 union select * from v1;
+
+create or replace view v1 as select 0 OR 3 != 3, 0 OR (3 != 3), (0 OR 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 != 3, 0 OR (3 != 3), (0 OR 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 LIKE 3, 2 OR (3 LIKE 3), (2 OR 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 LIKE 3, 2 OR (3 LIKE 3), (2 OR 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 REGEXP 3, 2 OR (3 REGEXP 3), (2 OR 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 REGEXP 3, 2 OR (3 REGEXP 3), (2 OR 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 | 3, 2 OR (3 | 3), (2 OR 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 | 3, 2 OR (3 | 3), (2 OR 3) | 3 union select * from v1;
+
+create or replace view v1 as select 0 OR 2 & 2, 0 OR (2 & 2), (0 OR 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 2 & 2, 0 OR (2 & 2), (0 OR 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 << 3, 2 OR (3 << 3), (2 OR 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 << 3, 2 OR (3 << 3), (2 OR 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 >> 3, 2 OR (3 >> 3), (2 OR 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 >> 3, 2 OR (3 >> 3), (2 OR 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 OR '2000-01-01' +INTERVAL 1 DAY, 2 OR ('2000-01-01' +INTERVAL 1 DAY), (2 OR '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR '2000-01-01' +INTERVAL 1 DAY, 2 OR ('2000-01-01' +INTERVAL 1 DAY), (2 OR '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 OR 3 + 3, 2 OR (3 + 3), (2 OR 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 + 3, 2 OR (3 + 3), (2 OR 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 - 3, 2 OR (3 - 3), (2 OR 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 - 3, 2 OR (3 - 3), (2 OR 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 * 3, 2 OR (3 * 3), (2 OR 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 * 3, 2 OR (3 * 3), (2 OR 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 / 3, 2 OR (3 / 3), (2 OR 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 / 3, 2 OR (3 / 3), (2 OR 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 DIV 3, 2 OR (3 DIV 3), (2 OR 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 DIV 3, 2 OR (3 DIV 3), (2 OR 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 0 OR 3 MOD 3, 0 OR (3 MOD 3), (0 OR 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 MOD 3, 0 OR (3 MOD 3), (0 OR 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 0 OR 3 % 3, 0 OR (3 % 3), (0 OR 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 % 3, 0 OR (3 % 3), (0 OR 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 ^ 3, 2 OR (3 ^ 3), (2 OR 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 ^ 3, 2 OR (3 ^ 3), (2 OR 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 OR 3 BETWEEN 2 AND 3, 2 OR (3 BETWEEN 2 AND 3), (2 OR 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 BETWEEN 2 AND 3, 2 OR (3 BETWEEN 2 AND 3), (2 OR 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 || 3 COLLATE latin1_bin), charset(2 || (3 COLLATE latin1_bin)), charset((2 || 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 || 3 COLLATE latin1_bin), charset(2 || (3 COLLATE latin1_bin)), charset((2 || 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10) union select * from v1;
+
+create or replace view v1 as select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1 union select * from v1;
+
+create or replace view v1 as select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0 union select * from v1;
+
+create or replace view v1 as select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0 union select * from v1;
+
+create or replace view v1 as select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0 union select * from v1;
+
+create or replace view v1 as select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0 union select * from v1;
+
+create or replace view v1 as select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 | 3, 2 || (3 | 3), (2 || 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 | 3, 2 || (3 | 3), (2 || 3) | 3 union select * from v1;
+
+create or replace view v1 as select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 || 3 + 3, 2 || (3 + 3), (2 || 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 + 3, 2 || (3 + 3), (2 || 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 - 3, 2 || (3 - 3), (2 || 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 - 3, 2 || (3 - 3), (2 || 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 ^ 3, 2 || (3 ^ 3), (2 || 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 ^ 3, 2 || (3 ^ 3), (2 || 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select charset(2 XOR 3 COLLATE latin1_bin), charset(2 XOR (3 COLLATE latin1_bin)), charset((2 XOR 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 XOR 3 COLLATE latin1_bin), charset(2 XOR (3 COLLATE latin1_bin)), charset((2 XOR 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 IN (4,5), 2 XOR (3 IN (4,5)), (2 XOR 3) IN (4,5);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 IN (4,5), 2 XOR (3 IN (4,5)), (2 XOR 3) IN (4,5) union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 OR 3, 2 XOR (3 OR 3), (2 XOR 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 OR 3, 2 XOR (3 OR 3), (2 XOR 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 0 AND 0, 2 XOR (0 AND 0), (2 XOR 0) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 0 AND 0, 2 XOR (0 AND 0), (2 XOR 0) AND 0 union select * from v1;
+
+create or replace view v1 as select 2 XOR 0 && 0, 2 XOR (0 && 0), (2 XOR 0) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 0 && 0, 2 XOR (0 && 0), (2 XOR 0) && 0 union select * from v1;
+
+create or replace view v1 as select 2 XOR 2 = 3, 2 XOR (2 = 3), (2 XOR 2) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 2 = 3, 2 XOR (2 = 3), (2 XOR 2) = 3 union select * from v1;
+
+create or replace view v1 as select NULL XOR 3 <=> 3, NULL XOR (3 <=> 3), (NULL XOR 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NULL XOR 3 <=> 3, NULL XOR (3 <=> 3), (NULL XOR 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 1 >= 3, 2 XOR (1 >= 3), (2 XOR 1) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 1 >= 3, 2 XOR (1 >= 3), (2 XOR 1) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 <= 3, 2 XOR (3 <= 3), (2 XOR 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 <= 3, 2 XOR (3 <= 3), (2 XOR 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 1 < 3, 2 XOR (1 < 3), (2 XOR 1) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 1 < 3, 2 XOR (1 < 3), (2 XOR 1) < 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 2 <> 3, 2 XOR (2 <> 3), (2 XOR 2) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 2 <> 3, 2 XOR (2 <> 3), (2 XOR 2) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 > 3, 2 XOR (3 > 3), (2 XOR 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 > 3, 2 XOR (3 > 3), (2 XOR 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 2 != 3, 2 XOR (2 != 3), (2 XOR 2) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 2 != 3, 2 XOR (2 != 3), (2 XOR 2) != 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 1 LIKE 3, 2 XOR (1 LIKE 3), (2 XOR 1) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 1 LIKE 3, 2 XOR (1 LIKE 3), (2 XOR 1) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 1 REGEXP 3, 2 XOR (1 REGEXP 3), (2 XOR 1) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 1 REGEXP 3, 2 XOR (1 REGEXP 3), (2 XOR 1) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 | 3, 2 XOR (3 | 3), (2 XOR 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 | 3, 2 XOR (3 | 3), (2 XOR 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 0 & 0, 2 XOR (0 & 0), (2 XOR 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 0 & 0, 2 XOR (0 & 0), (2 XOR 0) & 0 union select * from v1;
+
+create or replace view v1 as select 0 XOR 3 << 3, 0 XOR (3 << 3), (0 XOR 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 XOR 3 << 3, 0 XOR (3 << 3), (0 XOR 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 >> 3, 2 XOR (3 >> 3), (2 XOR 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 >> 3, 2 XOR (3 >> 3), (2 XOR 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR '2000-01-01' +INTERVAL 1 DAY, 2 XOR ('2000-01-01' +INTERVAL 1 DAY), (2 XOR '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR '2000-01-01' +INTERVAL 1 DAY, 2 XOR ('2000-01-01' +INTERVAL 1 DAY), (2 XOR '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 + 3, 2 XOR (3 + 3), (2 XOR 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 + 3, 2 XOR (3 + 3), (2 XOR 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 - 3, 2 XOR (3 - 3), (2 XOR 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 - 3, 2 XOR (3 - 3), (2 XOR 3) - 3 union select * from v1;
+
+create or replace view v1 as select 0 XOR 3 * 3, 0 XOR (3 * 3), (0 XOR 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 XOR 3 * 3, 0 XOR (3 * 3), (0 XOR 3) * 3 union select * from v1;
+
+create or replace view v1 as select 0 XOR 3 / 3, 0 XOR (3 / 3), (0 XOR 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 XOR 3 / 3, 0 XOR (3 / 3), (0 XOR 3) / 3 union select * from v1;
+
+create or replace view v1 as select 0 XOR 3 DIV 3, 0 XOR (3 DIV 3), (0 XOR 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 XOR 3 DIV 3, 0 XOR (3 DIV 3), (0 XOR 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 MOD 3, 2 XOR (3 MOD 3), (2 XOR 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 MOD 3, 2 XOR (3 MOD 3), (2 XOR 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 % 3, 2 XOR (3 % 3), (2 XOR 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 % 3, 2 XOR (3 % 3), (2 XOR 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 ^ 3, 2 XOR (3 ^ 3), (2 XOR 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 ^ 3, 2 XOR (3 ^ 3), (2 XOR 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 BETWEEN 0 AND 3, 2 XOR (3 BETWEEN 0 AND 3), (2 XOR 3) BETWEEN 0 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 BETWEEN 0 AND 3, 2 XOR (3 BETWEEN 0 AND 3), (2 XOR 3) BETWEEN 0 AND 3 union select * from v1;
+
+create or replace view v1 as select 0 AND 3 IS FALSE, 0 AND (3 IS FALSE), (0 AND 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 AND 3 IS FALSE, 0 AND (3 IS FALSE), (0 AND 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 AND 3 COLLATE latin1_bin), charset(2 AND (3 COLLATE latin1_bin)), charset((2 AND 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 AND 3 COLLATE latin1_bin), charset(2 AND (3 COLLATE latin1_bin)), charset((2 AND 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 AND 3 IN (0,1), 2 AND (3 IN (0,1)), (2 AND 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 IN (0,1), 2 AND (3 IN (0,1)), (2 AND 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 0 AND 3 OR 3, 0 AND (3 OR 3), (0 AND 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 AND 3 OR 3, 0 AND (3 OR 3), (0 AND 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3 union select * from v1;
+
+create or replace view v1 as select 0 AND 3 XOR 3, 0 AND (3 XOR 3), (0 AND 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 AND 3 XOR 3, 0 AND (3 XOR 3), (0 AND 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 = 3, 2 AND (3 = 3), (2 AND 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 = 3, 2 AND (3 = 3), (2 AND 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 <=> 3, 2 AND (3 <=> 3), (2 AND 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 <=> 3, 2 AND (3 <=> 3), (2 AND 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 >= 3, 2 AND (3 >= 3), (2 AND 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 >= 3, 2 AND (3 >= 3), (2 AND 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 4 <= 3, 2 AND (4 <= 3), (2 AND 4) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 4 <= 3, 2 AND (4 <= 3), (2 AND 4) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 < 3, 2 AND (3 < 3), (2 AND 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 < 3, 2 AND (3 < 3), (2 AND 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 <> 3, 2 AND (3 <> 3), (2 AND 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 <> 3, 2 AND (3 <> 3), (2 AND 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 > 1, 2 AND (3 > 1), (2 AND 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 > 1, 2 AND (3 > 1), (2 AND 3) > 1 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 != 3, 2 AND (3 != 3), (2 AND 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 != 3, 2 AND (3 != 3), (2 AND 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 LIKE 3, 2 AND (3 LIKE 3), (2 AND 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 LIKE 3, 2 AND (3 LIKE 3), (2 AND 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 REGEXP 3, 2 AND (3 REGEXP 3), (2 AND 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 REGEXP 3, 2 AND (3 REGEXP 3), (2 AND 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 | 3, 2 AND (3 | 3), (2 AND 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 | 3, 2 AND (3 | 3), (2 AND 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 2 & 2, 2 AND (2 & 2), (2 AND 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 2 & 2, 2 AND (2 & 2), (2 AND 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 << 3, 2 AND (3 << 3), (2 AND 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 << 3, 2 AND (3 << 3), (2 AND 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 >> 1, 2 AND (3 >> 1), (2 AND 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 >> 1, 2 AND (3 >> 1), (2 AND 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 AND '2000-01-01' +INTERVAL 1 DAY, 2 AND ('2000-01-01' +INTERVAL 1 DAY), (2 AND '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND '2000-01-01' +INTERVAL 1 DAY, 2 AND ('2000-01-01' +INTERVAL 1 DAY), (2 AND '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 AND 3 + 3, 2 AND (3 + 3), (2 AND 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 + 3, 2 AND (3 + 3), (2 AND 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 - 3, 2 AND (3 - 3), (2 AND 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 - 3, 2 AND (3 - 3), (2 AND 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 * 3, 2 AND (3 * 3), (2 AND 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 * 3, 2 AND (3 * 3), (2 AND 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 / 3, 2 AND (3 / 3), (2 AND 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 / 3, 2 AND (3 / 3), (2 AND 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 DIV 3, 2 AND (3 DIV 3), (2 AND 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 DIV 3, 2 AND (3 DIV 3), (2 AND 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 MOD 3, 2 AND (3 MOD 3), (2 AND 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 MOD 3, 2 AND (3 MOD 3), (2 AND 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 % 3, 2 AND (3 % 3), (2 AND 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 % 3, 2 AND (3 % 3), (2 AND 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 ^ 3, 2 AND (3 ^ 3), (2 AND 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 ^ 3, 2 AND (3 ^ 3), (2 AND 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 AND 3 BETWEEN 2 AND 3, 2 AND (3 BETWEEN 2 AND 3), (2 AND 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 BETWEEN 2 AND 3, 2 AND (3 BETWEEN 2 AND 3), (2 AND 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 0 && 3 IS FALSE, 0 && (3 IS FALSE), (0 && 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 && 3 IS FALSE, 0 && (3 IS FALSE), (0 && 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 && 3 COLLATE latin1_bin), charset(2 && (3 COLLATE latin1_bin)), charset((2 && 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 && 3 COLLATE latin1_bin), charset(2 && (3 COLLATE latin1_bin)), charset((2 && 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 && 3 IN (0,1), 2 && (3 IN (0,1)), (2 && 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 IN (0,1), 2 && (3 IN (0,1)), (2 && 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 0 && 3 OR 3, 0 && (3 OR 3), (0 && 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 && 3 OR 3, 0 && (3 OR 3), (0 && 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3 union select * from v1;
+
+create or replace view v1 as select 0 && 3 XOR 3, 0 && (3 XOR 3), (0 && 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 && 3 XOR 3, 0 && (3 XOR 3), (0 && 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 = 3, 2 && (3 = 3), (2 && 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 = 3, 2 && (3 = 3), (2 && 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 <=> 3, 2 && (3 <=> 3), (2 && 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 <=> 3, 2 && (3 <=> 3), (2 && 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 >= 3, 2 && (3 >= 3), (2 && 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 >= 3, 2 && (3 >= 3), (2 && 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 && 4 <= 3, 2 && (4 <= 3), (2 && 4) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 4 <= 3, 2 && (4 <= 3), (2 && 4) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 < 3, 2 && (3 < 3), (2 && 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 < 3, 2 && (3 < 3), (2 && 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 <> 3, 2 && (3 <> 3), (2 && 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 <> 3, 2 && (3 <> 3), (2 && 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 > 1, 2 && (3 > 1), (2 && 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 > 1, 2 && (3 > 1), (2 && 3) > 1 union select * from v1;
+
+create or replace view v1 as select 2 && 3 != 3, 2 && (3 != 3), (2 && 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 != 3, 2 && (3 != 3), (2 && 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 LIKE 3, 2 && (3 LIKE 3), (2 && 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 LIKE 3, 2 && (3 LIKE 3), (2 && 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 REGEXP 3, 2 && (3 REGEXP 3), (2 && 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 REGEXP 3, 2 && (3 REGEXP 3), (2 && 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 | 3, 2 && (3 | 3), (2 && 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 | 3, 2 && (3 | 3), (2 && 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 && 2 & 2, 2 && (2 & 2), (2 && 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 2 & 2, 2 && (2 & 2), (2 && 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 && 3 << 3, 2 && (3 << 3), (2 && 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 << 3, 2 && (3 << 3), (2 && 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 >> 1, 2 && (3 >> 1), (2 && 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 >> 1, 2 && (3 >> 1), (2 && 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 && '2000-01-01' +INTERVAL 1 DAY, 2 && ('2000-01-01' +INTERVAL 1 DAY), (2 && '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && '2000-01-01' +INTERVAL 1 DAY, 2 && ('2000-01-01' +INTERVAL 1 DAY), (2 && '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 && 3 + 3, 2 && (3 + 3), (2 && 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 + 3, 2 && (3 + 3), (2 && 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 - 3, 2 && (3 - 3), (2 && 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 - 3, 2 && (3 - 3), (2 && 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 * 3, 2 && (3 * 3), (2 && 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 * 3, 2 && (3 * 3), (2 && 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 / 3, 2 && (3 / 3), (2 && 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 / 3, 2 && (3 / 3), (2 && 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 DIV 3, 2 && (3 DIV 3), (2 && 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 DIV 3, 2 && (3 DIV 3), (2 && 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 MOD 3, 2 && (3 MOD 3), (2 && 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 MOD 3, 2 && (3 MOD 3), (2 && 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 % 3, 2 && (3 % 3), (2 && 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 % 3, 2 && (3 % 3), (2 && 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 ^ 3, 2 && (3 ^ 3), (2 && 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 ^ 3, 2 && (3 ^ 3), (2 && 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 && 3 BETWEEN 2 AND 3, 2 && (3 BETWEEN 2 AND 3), (2 && 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 BETWEEN 2 AND 3, 2 && (3 BETWEEN 2 AND 3), (2 && 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 IS FALSE, 2 = (3 IS FALSE), (2 = 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 IS FALSE, 2 = (3 IS FALSE), (2 = 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 = 3 COLLATE latin1_bin), charset(2 = (3 COLLATE latin1_bin)), charset((2 = 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 = 3 COLLATE latin1_bin), charset(2 = (3 COLLATE latin1_bin)), charset((2 = 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 = 3 IN (0,1), 2 = (3 IN (0,1)), (2 = 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 IN (0,1), 2 = (3 IN (0,1)), (2 = 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 = 3 OR 3, 2 = (3 OR 3), (2 = 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 OR 3, 2 = (3 OR 3), (2 = 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 XOR 3, 2 = (3 XOR 3), (2 = 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 XOR 3, 2 = (3 XOR 3), (2 = 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 = 2 AND 2, 2 = (2 AND 2), (2 = 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 2 AND 2, 2 = (2 AND 2), (2 = 2) AND 2 union select * from v1;
+
+create or replace view v1 as select 2 = 2 && 2, 2 = (2 && 2), (2 = 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 2 && 2, 2 = (2 && 2), (2 = 2) && 2 union select * from v1;
+
+create or replace view v1 as select 1 = 3 = 3, 1 = (3 = 3), (1 = 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 = 3, 1 = (3 = 3), (1 = 3) = 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 <=> 3, 1 = (3 <=> 3), (1 = 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 <=> 3, 1 = (3 <=> 3), (1 = 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 >= 3, 1 = (3 >= 3), (1 = 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 >= 3, 1 = (3 >= 3), (1 = 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 <= 3, 2 = (3 <= 3), (2 = 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 <= 3, 2 = (3 <= 3), (2 = 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 < 3, 2 = (3 < 3), (2 = 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 < 3, 2 = (3 < 3), (2 = 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 <> 3, 2 = (3 <> 3), (2 = 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 <> 3, 2 = (3 <> 3), (2 = 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 0 = 3 > 3, 0 = (3 > 3), (0 = 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 = 3 > 3, 0 = (3 > 3), (0 = 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 != 3, 2 = (3 != 3), (2 = 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 != 3, 2 = (3 != 3), (2 = 3) != 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 LIKE 3, 1 = (3 LIKE 3), (1 = 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 LIKE 3, 1 = (3 LIKE 3), (1 = 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 REGEXP 3, 1 = (3 REGEXP 3), (1 = 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 REGEXP 3, 1 = (3 REGEXP 3), (1 = 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 | 3, 2 = (3 | 3), (2 = 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 | 3, 2 = (3 | 3), (2 = 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 & 2, 2 = (3 & 2), (2 = 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 & 2, 2 = (3 & 2), (2 = 3) & 2 union select * from v1;
+
+create or replace view v1 as select 3 = 3 << 3, 3 = (3 << 3), (3 = 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 3 << 3, 3 = (3 << 3), (3 = 3) << 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 >> 1, 1 = (3 >> 1), (1 = 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 >> 1, 1 = (3 >> 1), (1 = 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 = '2000-01-01' +INTERVAL 1 DAY, 2 = ('2000-01-01' +INTERVAL 1 DAY), (2 = '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = '2000-01-01' +INTERVAL 1 DAY, 2 = ('2000-01-01' +INTERVAL 1 DAY), (2 = '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 = 3 + 3, 2 = (3 + 3), (2 = 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 + 3, 2 = (3 + 3), (2 = 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 - 3, 2 = (3 - 3), (2 = 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 - 3, 2 = (3 - 3), (2 = 3) - 3 union select * from v1;
+
+create or replace view v1 as select 3 = 3 * 3, 3 = (3 * 3), (3 = 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 3 * 3, 3 = (3 * 3), (3 = 3) * 3 union select * from v1;
+
+create or replace view v1 as select 3 = 9 / 3, 3 = (9 / 3), (3 = 9) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 9 / 3, 3 = (9 / 3), (3 = 9) / 3 union select * from v1;
+
+create or replace view v1 as select 3 = 9 DIV 3, 3 = (9 DIV 3), (3 = 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 9 DIV 3, 3 = (9 DIV 3), (3 = 9) DIV 3 union select * from v1;
+
+create or replace view v1 as select 3 = 3 MOD 3, 3 = (3 MOD 3), (3 = 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 3 MOD 3, 3 = (3 MOD 3), (3 = 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 3 = 3 % 3, 3 = (3 % 3), (3 = 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 = 3 % 3, 3 = (3 % 3), (3 = 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 ^ 3, 2 = (3 ^ 3), (2 = 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 ^ 3, 2 = (3 ^ 3), (2 = 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 1 = 3 BETWEEN 1 AND 3, 1 = (3 BETWEEN 1 AND 3), (1 = 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 = 3 BETWEEN 1 AND 3, 1 = (3 BETWEEN 1 AND 3), (1 = 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 IS FALSE, 2 <=> (3 IS FALSE), (2 <=> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 IS FALSE, 2 <=> (3 IS FALSE), (2 <=> 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 <=> 3 COLLATE latin1_bin), charset(2 <=> (3 COLLATE latin1_bin)), charset((2 <=> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 <=> 3 COLLATE latin1_bin), charset(2 <=> (3 COLLATE latin1_bin)), charset((2 <=> 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 IN (0,1), 2 <=> (3 IN (0,1)), (2 <=> 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 IN (0,1), 2 <=> (3 IN (0,1)), (2 <=> 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 OR 3, 2 <=> (3 OR 3), (2 <=> 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 OR 3, 2 <=> (3 OR 3), (2 <=> 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 XOR 3, 2 <=> (3 XOR 3), (2 <=> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 XOR 3, 2 <=> (3 XOR 3), (2 <=> 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 2 AND 2, 2 <=> (2 AND 2), (2 <=> 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 2 AND 2, 2 <=> (2 AND 2), (2 <=> 2) AND 2 union select * from v1;
+
+create or replace view v1 as select 2 <=> 2 && 2, 2 <=> (2 && 2), (2 <=> 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 2 && 2, 2 <=> (2 && 2), (2 <=> 2) && 2 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 = 3, 1 <=> (3 = 3), (1 <=> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 = 3, 1 <=> (3 = 3), (1 <=> 3) = 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 <=> 3, 1 <=> (3 <=> 3), (1 <=> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 <=> 3, 1 <=> (3 <=> 3), (1 <=> 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 >= 3, 1 <=> (3 >= 3), (1 <=> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 >= 3, 1 <=> (3 >= 3), (1 <=> 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 <= 3, 2 <=> (3 <= 3), (2 <=> 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 <= 3, 2 <=> (3 <= 3), (2 <=> 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 < 3, 2 <=> (3 < 3), (2 <=> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 < 3, 2 <=> (3 < 3), (2 <=> 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 <> 3, 2 <=> (3 <> 3), (2 <=> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 <> 3, 2 <=> (3 <> 3), (2 <=> 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 0 <=> 3 > 3, 0 <=> (3 > 3), (0 <=> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 <=> 3 > 3, 0 <=> (3 > 3), (0 <=> 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 != 3, 2 <=> (3 != 3), (2 <=> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 != 3, 2 <=> (3 != 3), (2 <=> 3) != 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 LIKE 3, 1 <=> (3 LIKE 3), (1 <=> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 LIKE 3, 1 <=> (3 LIKE 3), (1 <=> 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 REGEXP 3, 1 <=> (3 REGEXP 3), (1 <=> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 REGEXP 3, 1 <=> (3 REGEXP 3), (1 <=> 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 | 3, 2 <=> (3 | 3), (2 <=> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 | 3, 2 <=> (3 | 3), (2 <=> 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 & 2, 2 <=> (3 & 2), (2 <=> 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 & 2, 2 <=> (3 & 2), (2 <=> 3) & 2 union select * from v1;
+
+create or replace view v1 as select 3 <=> 3 << 3, 3 <=> (3 << 3), (3 <=> 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 3 << 3, 3 <=> (3 << 3), (3 <=> 3) << 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 >> 1, 1 <=> (3 >> 1), (1 <=> 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 >> 1, 1 <=> (3 >> 1), (1 <=> 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 <=> '2000-01-01' +INTERVAL 1 DAY, 2 <=> ('2000-01-01' +INTERVAL 1 DAY), (2 <=> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> '2000-01-01' +INTERVAL 1 DAY, 2 <=> ('2000-01-01' +INTERVAL 1 DAY), (2 <=> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 + 3, 2 <=> (3 + 3), (2 <=> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 + 3, 2 <=> (3 + 3), (2 <=> 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 - 3, 2 <=> (3 - 3), (2 <=> 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 - 3, 2 <=> (3 - 3), (2 <=> 3) - 3 union select * from v1;
+
+create or replace view v1 as select 3 <=> 3 * 3, 3 <=> (3 * 3), (3 <=> 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 3 * 3, 3 <=> (3 * 3), (3 <=> 3) * 3 union select * from v1;
+
+create or replace view v1 as select 3 <=> 9 / 3, 3 <=> (9 / 3), (3 <=> 9) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 9 / 3, 3 <=> (9 / 3), (3 <=> 9) / 3 union select * from v1;
+
+create or replace view v1 as select 3 <=> 9 DIV 3, 3 <=> (9 DIV 3), (3 <=> 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 9 DIV 3, 3 <=> (9 DIV 3), (3 <=> 9) DIV 3 union select * from v1;
+
+create or replace view v1 as select 3 <=> 3 MOD 3, 3 <=> (3 MOD 3), (3 <=> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 3 MOD 3, 3 <=> (3 MOD 3), (3 <=> 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 3 <=> 3 % 3, 3 <=> (3 % 3), (3 <=> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <=> 3 % 3, 3 <=> (3 % 3), (3 <=> 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 ^ 3, 2 <=> (3 ^ 3), (2 <=> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 ^ 3, 2 <=> (3 ^ 3), (2 <=> 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 1 <=> 3 BETWEEN 1 AND 3, 1 <=> (3 BETWEEN 1 AND 3), (1 <=> 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <=> 3 BETWEEN 1 AND 3, 1 <=> (3 BETWEEN 1 AND 3), (1 <=> 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 4 >= 3 IS FALSE, 4 >= (3 IS FALSE), (4 >= 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 >= 3 IS FALSE, 4 >= (3 IS FALSE), (4 >= 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 >= 3 COLLATE latin1_bin), charset(2 >= (3 COLLATE latin1_bin)), charset((2 >= 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 >= 3 COLLATE latin1_bin), charset(2 >= (3 COLLATE latin1_bin)), charset((2 >= 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 >= 3 IN (1,1), 2 >= (3 IN (1,1)), (2 >= 3) IN (1,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 IN (1,1), 2 >= (3 IN (1,1)), (2 >= 3) IN (1,1) union select * from v1;
+
+create or replace view v1 as select 2 >= 3 OR 0, 2 >= (3 OR 0), (2 >= 3) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 OR 0, 2 >= (3 OR 0), (2 >= 3) OR 0 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 XOR 0, 2 >= (3 XOR 0), (2 >= 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 XOR 0, 2 >= (3 XOR 0), (2 >= 3) XOR 0 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 AND 3, 2 >= (3 AND 3), (2 >= 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 AND 3, 2 >= (3 AND 3), (2 >= 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 && 3, 2 >= (3 && 3), (2 >= 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 && 3, 2 >= (3 && 3), (2 >= 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 = 3, 2 >= (3 = 3), (2 >= 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 = 3, 2 >= (3 = 3), (2 >= 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 <=> 3, 2 >= (3 <=> 3), (2 >= 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 <=> 3, 2 >= (3 <=> 3), (2 >= 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 >= 3, 2 >= (3 >= 3), (2 >= 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 >= 3, 2 >= (3 >= 3), (2 >= 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 0 >= 3 <= 3, 0 >= (3 <= 3), (0 >= 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 >= 3 <= 3, 0 >= (3 <= 3), (0 >= 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 0 >= 2 < 3, 0 >= (2 < 3), (0 >= 2) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 >= 2 < 3, 0 >= (2 < 3), (0 >= 2) < 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 <> 0, 2 >= (3 <> 0), (2 >= 3) <> 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 <> 0, 2 >= (3 <> 0), (2 >= 3) <> 0 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 > 3, 2 >= (3 > 3), (2 >= 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 > 3, 2 >= (3 > 3), (2 >= 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 != 0, 2 >= (3 != 0), (2 >= 3) != 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 != 0, 2 >= (3 != 0), (2 >= 3) != 0 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 LIKE 3, 2 >= (3 LIKE 3), (2 >= 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 LIKE 3, 2 >= (3 LIKE 3), (2 >= 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 REGEXP 3, 2 >= (3 REGEXP 3), (2 >= 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 REGEXP 3, 2 >= (3 REGEXP 3), (2 >= 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 | 3, 2 >= (3 | 3), (2 >= 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 | 3, 2 >= (3 | 3), (2 >= 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 & 1, 2 >= (3 & 1), (2 >= 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 & 1, 2 >= (3 & 1), (2 >= 3) & 1 union select * from v1;
+
+create or replace view v1 as select 3 >= 3 << 3, 3 >= (3 << 3), (3 >= 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 >= 3 << 3, 3 >= (3 << 3), (3 >= 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 >> 3, 2 >= (3 >> 3), (2 >= 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 >> 3, 2 >= (3 >> 3), (2 >= 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 >= '2000-01-01' +INTERVAL 1 DAY, 2 >= ('2000-01-01' +INTERVAL 1 DAY), (2 >= '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= '2000-01-01' +INTERVAL 1 DAY, 2 >= ('2000-01-01' +INTERVAL 1 DAY), (2 >= '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 >= 3 + 3, 2 >= (3 + 3), (2 >= 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 + 3, 2 >= (3 + 3), (2 >= 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 - 3, 2 >= (3 - 3), (2 >= 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 - 3, 2 >= (3 - 3), (2 >= 3) - 3 union select * from v1;
+
+create or replace view v1 as select 3 >= 3 * 3, 3 >= (3 * 3), (3 >= 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 >= 3 * 3, 3 >= (3 * 3), (3 >= 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 / 3, 2 >= (3 / 3), (2 >= 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 / 3, 2 >= (3 / 3), (2 >= 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 DIV 3, 2 >= (3 DIV 3), (2 >= 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 DIV 3, 2 >= (3 DIV 3), (2 >= 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 MOD 3, 2 >= (3 MOD 3), (2 >= 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 MOD 3, 2 >= (3 MOD 3), (2 >= 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 % 3, 2 >= (3 % 3), (2 >= 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 % 3, 2 >= (3 % 3), (2 >= 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 ^ 3, 2 >= (3 ^ 3), (2 >= 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 ^ 3, 2 >= (3 ^ 3), (2 >= 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 BETWEEN 1 AND 3, 2 >= (3 BETWEEN 1 AND 3), (2 >= 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 BETWEEN 1 AND 3, 2 >= (3 BETWEEN 1 AND 3), (2 >= 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 1 IS FALSE, 2 <= (1 IS FALSE), (2 <= 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 1 IS FALSE, 2 <= (1 IS FALSE), (2 <= 1) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 <= 3 COLLATE latin1_bin), charset(2 <= (3 COLLATE latin1_bin)), charset((2 <= 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 <= 3 COLLATE latin1_bin), charset(2 <= (3 COLLATE latin1_bin)), charset((2 <= 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 <= 3 IN (0,1), 2 <= (3 IN (0,1)), (2 <= 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 IN (0,1), 2 <= (3 IN (0,1)), (2 <= 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 <= 3 OR 3, 2 <= (3 OR 3), (2 <= 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 OR 3, 2 <= (3 OR 3), (2 <= 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 1 XOR 1, 2 <= (1 XOR 1), (2 <= 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 1 XOR 1, 2 <= (1 XOR 1), (2 <= 1) XOR 1 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 AND 3, 2 <= (3 AND 3), (2 <= 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 AND 3, 2 <= (3 AND 3), (2 <= 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 && 3, 2 <= (3 && 3), (2 <= 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 && 3, 2 <= (3 && 3), (2 <= 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 0 = 0, 2 <= (0 = 0), (2 <= 0) = 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 0 = 0, 2 <= (0 = 0), (2 <= 0) = 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 0 <=> 0, 2 <= (0 <=> 0), (2 <= 0) <=> 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 0 <=> 0, 2 <= (0 <=> 0), (2 <= 0) <=> 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 0 >= 0, 2 <= (0 >= 0), (2 <= 0) >= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 0 >= 0, 2 <= (0 >= 0), (2 <= 0) >= 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 <= 3, 2 <= (3 <= 3), (2 <= 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 <= 3, 2 <= (3 <= 3), (2 <= 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 < 3, 2 <= (3 < 3), (2 <= 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 < 3, 2 <= (3 < 3), (2 <= 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 <> 3, 2 <= (3 <> 3), (2 <= 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 <> 3, 2 <= (3 <> 3), (2 <= 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 > 0, 2 <= (3 > 0), (2 <= 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 > 0, 2 <= (3 > 0), (2 <= 3) > 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 != 3, 2 <= (3 != 3), (2 <= 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 != 3, 2 <= (3 != 3), (2 <= 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 0 LIKE 0, 2 <= (0 LIKE 0), (2 <= 0) LIKE 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 0 LIKE 0, 2 <= (0 LIKE 0), (2 <= 0) LIKE 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 0 REGEXP 0, 2 <= (0 REGEXP 0), (2 <= 0) REGEXP 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 0 REGEXP 0, 2 <= (0 REGEXP 0), (2 <= 0) REGEXP 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 | 3, 2 <= (3 | 3), (2 <= 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 | 3, 2 <= (3 | 3), (2 <= 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 & 2, 2 <= (3 & 2), (2 <= 3) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 & 2, 2 <= (3 & 2), (2 <= 3) & 2 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 << 3, 2 <= (3 << 3), (2 <= 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 << 3, 2 <= (3 << 3), (2 <= 3) << 3 union select * from v1;
+
+create or replace view v1 as select 0 <= 3 >> 1, 0 <= (3 >> 1), (0 <= 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 <= 3 >> 1, 0 <= (3 >> 1), (0 <= 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 <= '2000-01-01' +INTERVAL 1 DAY, 2 <= ('2000-01-01' +INTERVAL 1 DAY), (2 <= '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= '2000-01-01' +INTERVAL 1 DAY, 2 <= ('2000-01-01' +INTERVAL 1 DAY), (2 <= '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 <= 3 + 3, 2 <= (3 + 3), (2 <= 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 + 3, 2 <= (3 + 3), (2 <= 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 - 3, 2 <= (3 - 3), (2 <= 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 - 3, 2 <= (3 - 3), (2 <= 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 * 3, 2 <= (3 * 3), (2 <= 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 * 3, 2 <= (3 * 3), (2 <= 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 / 3, 2 <= (3 / 3), (2 <= 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 / 3, 2 <= (3 / 3), (2 <= 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 9 DIV 3, 2 <= (9 DIV 3), (2 <= 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 9 DIV 3, 2 <= (9 DIV 3), (2 <= 9) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 MOD 3, 2 <= (3 MOD 3), (2 <= 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 MOD 3, 2 <= (3 MOD 3), (2 <= 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 % 3, 2 <= (3 % 3), (2 <= 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 % 3, 2 <= (3 % 3), (2 <= 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 ^ 3, 2 <= (3 ^ 3), (2 <= 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 ^ 3, 2 <= (3 ^ 3), (2 <= 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 BETWEEN 1 AND 3, 2 <= (3 BETWEEN 1 AND 3), (2 <= 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 BETWEEN 1 AND 3, 2 <= (3 BETWEEN 1 AND 3), (2 <= 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 < 1 IS FALSE, 2 < (1 IS FALSE), (2 < 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 1 IS FALSE, 2 < (1 IS FALSE), (2 < 1) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 < 3 COLLATE latin1_bin), charset(2 < (3 COLLATE latin1_bin)), charset((2 < 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 < 3 COLLATE latin1_bin), charset(2 < (3 COLLATE latin1_bin)), charset((2 < 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 < 3 IN (0,1), 2 < (3 IN (0,1)), (2 < 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 IN (0,1), 2 < (3 IN (0,1)), (2 < 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 < 3 OR 3, 2 < (3 OR 3), (2 < 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 OR 3, 2 < (3 OR 3), (2 < 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 XOR 0, 2 < (3 XOR 0), (2 < 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 XOR 0, 2 < (3 XOR 0), (2 < 3) XOR 0 union select * from v1;
+
+create or replace view v1 as select 2 < 3 AND 3, 2 < (3 AND 3), (2 < 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 AND 3, 2 < (3 AND 3), (2 < 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 && 3, 2 < (3 && 3), (2 < 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 && 3, 2 < (3 && 3), (2 < 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 = 1, 2 < (3 = 1), (2 < 3) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 = 1, 2 < (3 = 1), (2 < 3) = 1 union select * from v1;
+
+create or replace view v1 as select 2 < 3 <=> 1, 2 < (3 <=> 1), (2 < 3) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 <=> 1, 2 < (3 <=> 1), (2 < 3) <=> 1 union select * from v1;
+
+create or replace view v1 as select 2 < 3 >= 1, 2 < (3 >= 1), (2 < 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 >= 1, 2 < (3 >= 1), (2 < 3) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 < 3 <= 3, 2 < (3 <= 3), (2 < 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 <= 3, 2 < (3 <= 3), (2 < 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 < 3, 2 < (3 < 3), (2 < 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 < 3, 2 < (3 < 3), (2 < 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 <> 3, 2 < (3 <> 3), (2 < 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 <> 3, 2 < (3 <> 3), (2 < 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 > 0, 2 < (3 > 0), (2 < 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 > 0, 2 < (3 > 0), (2 < 3) > 0 union select * from v1;
+
+create or replace view v1 as select 2 < 3 != 3, 2 < (3 != 3), (2 < 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 != 3, 2 < (3 != 3), (2 < 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 LIKE 1, 2 < (3 LIKE 1), (2 < 3) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 LIKE 1, 2 < (3 LIKE 1), (2 < 3) LIKE 1 union select * from v1;
+
+create or replace view v1 as select 2 < 3 REGEXP 1, 2 < (3 REGEXP 1), (2 < 3) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 REGEXP 1, 2 < (3 REGEXP 1), (2 < 3) REGEXP 1 union select * from v1;
+
+create or replace view v1 as select 2 < 3 | 3, 2 < (3 | 3), (2 < 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 | 3, 2 < (3 | 3), (2 < 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 < 4 & 4, 2 < (4 & 4), (2 < 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 4 & 4, 2 < (4 & 4), (2 < 4) & 4 union select * from v1;
+
+create or replace view v1 as select 2 < 3 << 3, 2 < (3 << 3), (2 < 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 << 3, 2 < (3 << 3), (2 < 3) << 3 union select * from v1;
+
+create or replace view v1 as select 0 < 3 >> 1, 0 < (3 >> 1), (0 < 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 < 3 >> 1, 0 < (3 >> 1), (0 < 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 < '2000-01-01' +INTERVAL 1 DAY, 2 < ('2000-01-01' +INTERVAL 1 DAY), (2 < '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < '2000-01-01' +INTERVAL 1 DAY, 2 < ('2000-01-01' +INTERVAL 1 DAY), (2 < '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 < 3 + 3, 2 < (3 + 3), (2 < 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 + 3, 2 < (3 + 3), (2 < 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 - 3, 2 < (3 - 3), (2 < 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 - 3, 2 < (3 - 3), (2 < 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 * 3, 2 < (3 * 3), (2 < 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 * 3, 2 < (3 * 3), (2 < 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 / 3, 2 < (3 / 3), (2 < 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 / 3, 2 < (3 / 3), (2 < 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 < 9 DIV 3, 2 < (9 DIV 3), (2 < 9) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 9 DIV 3, 2 < (9 DIV 3), (2 < 9) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 MOD 3, 2 < (3 MOD 3), (2 < 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 MOD 3, 2 < (3 MOD 3), (2 < 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 % 3, 2 < (3 % 3), (2 < 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 % 3, 2 < (3 % 3), (2 < 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 ^ 3, 2 < (3 ^ 3), (2 < 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 ^ 3, 2 < (3 ^ 3), (2 < 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 BETWEEN 1 AND 3, 2 < (3 BETWEEN 1 AND 3), (2 < 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 BETWEEN 1 AND 3, 2 < (3 BETWEEN 1 AND 3), (2 < 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 IS FALSE, 2 <> (3 IS FALSE), (2 <> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 IS FALSE, 2 <> (3 IS FALSE), (2 <> 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 <> 3 COLLATE latin1_bin), charset(2 <> (3 COLLATE latin1_bin)), charset((2 <> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 <> 3 COLLATE latin1_bin), charset(2 <> (3 COLLATE latin1_bin)), charset((2 <> 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 <> 3 IN (0,0), 2 <> (3 IN (0,0)), (2 <> 3) IN (0,0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 IN (0,0), 2 <> (3 IN (0,0)), (2 <> 3) IN (0,0) union select * from v1;
+
+create or replace view v1 as select 1 <> 3 OR 3, 1 <> (3 OR 3), (1 <> 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <> 3 OR 3, 1 <> (3 OR 3), (1 <> 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 XOR 3, 2 <> (3 XOR 3), (2 <> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 XOR 3, 2 <> (3 XOR 3), (2 <> 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 3 <> 3 AND 3, 3 <> (3 AND 3), (3 <> 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <> 3 AND 3, 3 <> (3 AND 3), (3 <> 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 3 <> 3 && 3, 3 <> (3 && 3), (3 <> 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <> 3 && 3, 3 <> (3 && 3), (3 <> 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 = 3, 2 <> (3 = 3), (2 <> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 = 3, 2 <> (3 = 3), (2 <> 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 <=> 3, 2 <> (3 <=> 3), (2 <> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 <=> 3, 2 <> (3 <=> 3), (2 <> 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 >= 3, 2 <> (3 >= 3), (2 <> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 >= 3, 2 <> (3 >= 3), (2 <> 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 1 <> 3 <= 3, 1 <> (3 <= 3), (1 <> 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <> 3 <= 3, 1 <> (3 <= 3), (1 <> 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 0 <> 3 < 3, 0 <> (3 < 3), (0 <> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 <> 3 < 3, 0 <> (3 < 3), (0 <> 3) < 3 union select * from v1;
+
+create or replace view v1 as select 0 <> 3 <> 3, 0 <> (3 <> 3), (0 <> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 <> 3 <> 3, 0 <> (3 <> 3), (0 <> 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 > 3, 2 <> (3 > 3), (2 <> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 > 3, 2 <> (3 > 3), (2 <> 3) > 3 union select * from v1;
+
+create or replace view v1 as select 0 <> 3 != 3, 0 <> (3 != 3), (0 <> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 <> 3 != 3, 0 <> (3 != 3), (0 <> 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 LIKE 3, 2 <> (3 LIKE 3), (2 <> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 LIKE 3, 2 <> (3 LIKE 3), (2 <> 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 REGEXP 3, 2 <> (3 REGEXP 3), (2 <> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 REGEXP 3, 2 <> (3 REGEXP 3), (2 <> 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 | 3, 2 <> (3 | 3), (2 <> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 | 3, 2 <> (3 | 3), (2 <> 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 4 & 4, 2 <> (4 & 4), (2 <> 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 4 & 4, 2 <> (4 & 4), (2 <> 4) & 4 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 << 3, 2 <> (3 << 3), (2 <> 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 << 3, 2 <> (3 << 3), (2 <> 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 >> 3, 2 <> (3 >> 3), (2 <> 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 >> 3, 2 <> (3 >> 3), (2 <> 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 <> '2000-01-01' +INTERVAL 1 DAY, 2 <> ('2000-01-01' +INTERVAL 1 DAY), (2 <> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> '2000-01-01' +INTERVAL 1 DAY, 2 <> ('2000-01-01' +INTERVAL 1 DAY), (2 <> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 <> 3 + 3, 2 <> (3 + 3), (2 <> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 + 3, 2 <> (3 + 3), (2 <> 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 - 3, 2 <> (3 - 3), (2 <> 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 - 3, 2 <> (3 - 3), (2 <> 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 * 3, 2 <> (3 * 3), (2 <> 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 * 3, 2 <> (3 * 3), (2 <> 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 / 3, 2 <> (3 / 3), (2 <> 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 / 3, 2 <> (3 / 3), (2 <> 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 DIV 3, 2 <> (3 DIV 3), (2 <> 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 DIV 3, 2 <> (3 DIV 3), (2 <> 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 3 <> 3 MOD 3, 3 <> (3 MOD 3), (3 <> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <> 3 MOD 3, 3 <> (3 MOD 3), (3 <> 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 3 <> 3 % 3, 3 <> (3 % 3), (3 <> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 <> 3 % 3, 3 <> (3 % 3), (3 <> 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 ^ 3, 2 <> (3 ^ 3), (2 <> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 ^ 3, 2 <> (3 ^ 3), (2 <> 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 <> 3 BETWEEN 2 AND 3, 2 <> (3 BETWEEN 2 AND 3), (2 <> 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 BETWEEN 2 AND 3, 2 <> (3 BETWEEN 2 AND 3), (2 <> 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 > 0 IS FALSE, 2 > (0 IS FALSE), (2 > 0) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 0 IS FALSE, 2 > (0 IS FALSE), (2 > 0) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 > 3 COLLATE latin1_bin), charset(2 > (3 COLLATE latin1_bin)), charset((2 > 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 > 3 COLLATE latin1_bin), charset(2 > (3 COLLATE latin1_bin)), charset((2 > 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 > 3 IN (1,1), 2 > (3 IN (1,1)), (2 > 3) IN (1,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 IN (1,1), 2 > (3 IN (1,1)), (2 > 3) IN (1,1) union select * from v1;
+
+create or replace view v1 as select 0 > 3 OR 3, 0 > (3 OR 3), (0 > 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 > 3 OR 3, 0 > (3 OR 3), (0 > 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3 union select * from v1;
+
+create or replace view v1 as select 4 > 3 XOR 3, 4 > (3 XOR 3), (4 > 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 > 3 XOR 3, 4 > (3 XOR 3), (4 > 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 AND 3, 2 > (3 AND 3), (2 > 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 AND 3, 2 > (3 AND 3), (2 > 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 && 3, 2 > (3 && 3), (2 > 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 && 3, 2 > (3 && 3), (2 > 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 = 3, 2 > (3 = 3), (2 > 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 = 3, 2 > (3 = 3), (2 > 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 <=> 3, 2 > (3 <=> 3), (2 > 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 <=> 3, 2 > (3 <=> 3), (2 > 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 >= 3, 2 > (3 >= 3), (2 > 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 >= 3, 2 > (3 >= 3), (2 > 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 > 0 <= 0, 2 > (0 <= 0), (2 > 0) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 0 <= 0, 2 > (0 <= 0), (2 > 0) <= 0 union select * from v1;
+
+create or replace view v1 as select 2 > 0 < 0, 2 > (0 < 0), (2 > 0) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 0 < 0, 2 > (0 < 0), (2 > 0) < 0 union select * from v1;
+
+create or replace view v1 as select 2 > 1 <> 1, 2 > (1 <> 1), (2 > 1) <> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 1 <> 1, 2 > (1 <> 1), (2 > 1) <> 1 union select * from v1;
+
+create or replace view v1 as select 2 > 3 > 3, 2 > (3 > 3), (2 > 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 > 3, 2 > (3 > 3), (2 > 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 > 1 != 1, 2 > (1 != 1), (2 > 1) != 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 1 != 1, 2 > (1 != 1), (2 > 1) != 1 union select * from v1;
+
+create or replace view v1 as select 2 > 3 LIKE 3, 2 > (3 LIKE 3), (2 > 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 LIKE 3, 2 > (3 LIKE 3), (2 > 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 REGEXP 3, 2 > (3 REGEXP 3), (2 > 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 REGEXP 3, 2 > (3 REGEXP 3), (2 > 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 | 3, 2 > (3 | 3), (2 > 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 | 3, 2 > (3 | 3), (2 > 3) | 3 union select * from v1;
+
+create or replace view v1 as select 4 > 2 & 2, 4 > (2 & 2), (4 > 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 > 2 & 2, 4 > (2 & 2), (4 > 2) & 2 union select * from v1;
+
+create or replace view v1 as select 4 > 3 << 3, 4 > (3 << 3), (4 > 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 > 3 << 3, 4 > (3 << 3), (4 > 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 >> 3, 2 > (3 >> 3), (2 > 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 >> 3, 2 > (3 >> 3), (2 > 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 > '2000-01-01' +INTERVAL 1 DAY, 2 > ('2000-01-01' +INTERVAL 1 DAY), (2 > '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > '2000-01-01' +INTERVAL 1 DAY, 2 > ('2000-01-01' +INTERVAL 1 DAY), (2 > '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 > 3 + 3, 2 > (3 + 3), (2 > 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 + 3, 2 > (3 + 3), (2 > 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 - 3, 2 > (3 - 3), (2 > 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 - 3, 2 > (3 - 3), (2 > 3) - 3 union select * from v1;
+
+create or replace view v1 as select 4 > 3 * 3, 4 > (3 * 3), (4 > 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 > 3 * 3, 4 > (3 * 3), (4 > 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 / 3, 2 > (3 / 3), (2 > 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 / 3, 2 > (3 / 3), (2 > 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 DIV 3, 2 > (3 DIV 3), (2 > 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 DIV 3, 2 > (3 DIV 3), (2 > 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 MOD 3, 2 > (3 MOD 3), (2 > 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 MOD 3, 2 > (3 MOD 3), (2 > 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 % 3, 2 > (3 % 3), (2 > 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 % 3, 2 > (3 % 3), (2 > 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 ^ 3, 2 > (3 ^ 3), (2 > 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 ^ 3, 2 > (3 ^ 3), (2 > 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 > 3 BETWEEN 1 AND 3, 2 > (3 BETWEEN 1 AND 3), (2 > 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 BETWEEN 1 AND 3, 2 > (3 BETWEEN 1 AND 3), (2 > 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 IS FALSE, 2 != (3 IS FALSE), (2 != 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 IS FALSE, 2 != (3 IS FALSE), (2 != 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 != 3 COLLATE latin1_bin), charset(2 != (3 COLLATE latin1_bin)), charset((2 != 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 != 3 COLLATE latin1_bin), charset(2 != (3 COLLATE latin1_bin)), charset((2 != 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 != 3 IN (0,0), 2 != (3 IN (0,0)), (2 != 3) IN (0,0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 IN (0,0), 2 != (3 IN (0,0)), (2 != 3) IN (0,0) union select * from v1;
+
+create or replace view v1 as select 1 != 3 OR 3, 1 != (3 OR 3), (1 != 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 != 3 OR 3, 1 != (3 OR 3), (1 != 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 XOR 3, 2 != (3 XOR 3), (2 != 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 XOR 3, 2 != (3 XOR 3), (2 != 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 3 != 3 AND 3, 3 != (3 AND 3), (3 != 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 != 3 AND 3, 3 != (3 AND 3), (3 != 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 3 != 3 && 3, 3 != (3 && 3), (3 != 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 != 3 && 3, 3 != (3 && 3), (3 != 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 = 3, 2 != (3 = 3), (2 != 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 = 3, 2 != (3 = 3), (2 != 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 <=> 3, 2 != (3 <=> 3), (2 != 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 <=> 3, 2 != (3 <=> 3), (2 != 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 >= 3, 2 != (3 >= 3), (2 != 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 >= 3, 2 != (3 >= 3), (2 != 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 1 != 3 <= 3, 1 != (3 <= 3), (1 != 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 != 3 <= 3, 1 != (3 <= 3), (1 != 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 0 != 3 < 3, 0 != (3 < 3), (0 != 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 != 3 < 3, 0 != (3 < 3), (0 != 3) < 3 union select * from v1;
+
+create or replace view v1 as select 0 != 3 <> 3, 0 != (3 <> 3), (0 != 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 != 3 <> 3, 0 != (3 <> 3), (0 != 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 > 3, 2 != (3 > 3), (2 != 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 > 3, 2 != (3 > 3), (2 != 3) > 3 union select * from v1;
+
+create or replace view v1 as select 0 != 3 != 3, 0 != (3 != 3), (0 != 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 != 3 != 3, 0 != (3 != 3), (0 != 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 LIKE 3, 2 != (3 LIKE 3), (2 != 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 LIKE 3, 2 != (3 LIKE 3), (2 != 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 REGEXP 3, 2 != (3 REGEXP 3), (2 != 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 REGEXP 3, 2 != (3 REGEXP 3), (2 != 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 | 3, 2 != (3 | 3), (2 != 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 | 3, 2 != (3 | 3), (2 != 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 != 4 & 4, 2 != (4 & 4), (2 != 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 4 & 4, 2 != (4 & 4), (2 != 4) & 4 union select * from v1;
+
+create or replace view v1 as select 2 != 3 << 3, 2 != (3 << 3), (2 != 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 << 3, 2 != (3 << 3), (2 != 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 >> 3, 2 != (3 >> 3), (2 != 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 >> 3, 2 != (3 >> 3), (2 != 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 != '2000-01-01' +INTERVAL 1 DAY, 2 != ('2000-01-01' +INTERVAL 1 DAY), (2 != '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != '2000-01-01' +INTERVAL 1 DAY, 2 != ('2000-01-01' +INTERVAL 1 DAY), (2 != '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 != 3 + 3, 2 != (3 + 3), (2 != 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 + 3, 2 != (3 + 3), (2 != 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 - 3, 2 != (3 - 3), (2 != 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 - 3, 2 != (3 - 3), (2 != 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 * 3, 2 != (3 * 3), (2 != 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 * 3, 2 != (3 * 3), (2 != 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 / 3, 2 != (3 / 3), (2 != 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 / 3, 2 != (3 / 3), (2 != 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 DIV 3, 2 != (3 DIV 3), (2 != 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 DIV 3, 2 != (3 DIV 3), (2 != 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 3 != 3 MOD 3, 3 != (3 MOD 3), (3 != 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 != 3 MOD 3, 3 != (3 MOD 3), (3 != 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 3 != 3 % 3, 3 != (3 % 3), (3 != 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 != 3 % 3, 3 != (3 % 3), (3 != 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 ^ 3, 2 != (3 ^ 3), (2 != 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 ^ 3, 2 != (3 ^ 3), (2 != 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 != 3 BETWEEN 2 AND 3, 2 != (3 BETWEEN 2 AND 3), (2 != 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 BETWEEN 2 AND 3, 2 != (3 BETWEEN 2 AND 3), (2 != 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 IS FALSE, 2 LIKE (3 IS FALSE), (2 LIKE 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 IS FALSE, 2 LIKE (3 IS FALSE), (2 LIKE 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 LIKE 3 COLLATE latin1_bin), charset(2 LIKE (3 COLLATE latin1_bin)), charset((2 LIKE 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 LIKE 3 COLLATE latin1_bin), charset(2 LIKE (3 COLLATE latin1_bin)), charset((2 LIKE 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 IN (0,1), 2 LIKE (3 IN (0,1)), (2 LIKE 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 IN (0,1), 2 LIKE (3 IN (0,1)), (2 LIKE 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 OR 3, 2 LIKE (3 OR 3), (2 LIKE 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 OR 3, 2 LIKE (3 OR 3), (2 LIKE 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 XOR 3, 2 LIKE (3 XOR 3), (2 LIKE 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 XOR 3, 2 LIKE (3 XOR 3), (2 LIKE 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 AND 2, 2 LIKE (2 AND 2), (2 LIKE 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 AND 2, 2 LIKE (2 AND 2), (2 LIKE 2) AND 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 && 2, 2 LIKE (2 && 2), (2 LIKE 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 && 2, 2 LIKE (2 && 2), (2 LIKE 2) && 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 = 1, 2 LIKE (2 = 1), (2 LIKE 2) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 = 1, 2 LIKE (2 = 1), (2 LIKE 2) = 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 <=> 1, 2 LIKE (2 <=> 1), (2 LIKE 2) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 <=> 1, 2 LIKE (2 <=> 1), (2 LIKE 2) <=> 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 >= 1, 2 LIKE (2 >= 1), (2 LIKE 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 >= 1, 2 LIKE (2 >= 1), (2 LIKE 2) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 <= 3, 2 LIKE (3 <= 3), (2 LIKE 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 <= 3, 2 LIKE (3 <= 3), (2 LIKE 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 < 3, 2 LIKE (3 < 3), (2 LIKE 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 < 3, 2 LIKE (3 < 3), (2 LIKE 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 <> 3, 2 LIKE (3 <> 3), (2 LIKE 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 <> 3, 2 LIKE (3 <> 3), (2 LIKE 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 > 0, 2 LIKE (2 > 0), (2 LIKE 2) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 > 0, 2 LIKE (2 > 0), (2 LIKE 2) > 0 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 != 3, 2 LIKE (3 != 3), (2 LIKE 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 != 3, 2 LIKE (3 != 3), (2 LIKE 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 LIKE 1, 2 LIKE (2 LIKE 1), (2 LIKE 2) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 LIKE 1, 2 LIKE (2 LIKE 1), (2 LIKE 2) LIKE 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 REGEXP 1, 2 LIKE (2 REGEXP 1), (2 LIKE 2) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 REGEXP 1, 2 LIKE (2 REGEXP 1), (2 LIKE 2) REGEXP 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 | 3, 2 LIKE (3 | 3), (2 LIKE 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 | 3, 2 LIKE (3 | 3), (2 LIKE 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 & 2, 2 LIKE (2 & 2), (2 LIKE 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 & 2, 2 LIKE (2 & 2), (2 LIKE 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 << 2, 2 LIKE (2 << 2), (2 LIKE 2) << 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 << 2, 2 LIKE (2 << 2), (2 LIKE 2) << 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 4 >> 1, 2 LIKE (4 >> 1), (2 LIKE 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 4 >> 1, 2 LIKE (4 >> 1), (2 LIKE 4) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE '2000-01-01' +INTERVAL 1 DAY, 2 LIKE ('2000-01-01' +INTERVAL 1 DAY), (2 LIKE '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE '2000-01-01' +INTERVAL 1 DAY, 2 LIKE ('2000-01-01' +INTERVAL 1 DAY), (2 LIKE '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 + 3, 2 LIKE (3 + 3), (2 LIKE 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 + 3, 2 LIKE (3 + 3), (2 LIKE 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 - 3, 2 LIKE (3 - 3), (2 LIKE 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 - 3, 2 LIKE (3 - 3), (2 LIKE 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 * 2, 2 LIKE (2 * 2), (2 LIKE 2) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 * 2, 2 LIKE (2 * 2), (2 LIKE 2) * 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 / 2, 2 LIKE (2 / 2), (2 LIKE 2) / 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 / 2, 2 LIKE (2 / 2), (2 LIKE 2) / 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 4 DIV 2, 2 LIKE (4 DIV 2), (2 LIKE 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 4 DIV 2, 2 LIKE (4 DIV 2), (2 LIKE 4) DIV 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 MOD 2, 2 LIKE (2 MOD 2), (2 LIKE 2) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 MOD 2, 2 LIKE (2 MOD 2), (2 LIKE 2) MOD 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 % 2, 2 LIKE (2 % 2), (2 LIKE 2) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 % 2, 2 LIKE (2 % 2), (2 LIKE 2) % 2 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 ^ 3, 2 LIKE (3 ^ 3), (2 LIKE 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 ^ 3, 2 LIKE (3 ^ 3), (2 LIKE 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 BETWEEN 1 AND 3, 2 LIKE (2 BETWEEN 1 AND 3), (2 LIKE 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 BETWEEN 1 AND 3, 2 LIKE (2 BETWEEN 1 AND 3), (2 LIKE 2) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 IS FALSE, 2 REGEXP (3 IS FALSE), (2 REGEXP 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 IS FALSE, 2 REGEXP (3 IS FALSE), (2 REGEXP 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 REGEXP 3 COLLATE latin1_bin), charset(2 REGEXP (3 COLLATE latin1_bin)), charset((2 REGEXP 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 REGEXP 3 COLLATE latin1_bin), charset(2 REGEXP (3 COLLATE latin1_bin)), charset((2 REGEXP 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 IN (0,1), 2 REGEXP (3 IN (0,1)), (2 REGEXP 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 IN (0,1), 2 REGEXP (3 IN (0,1)), (2 REGEXP 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 OR 3, 2 REGEXP (3 OR 3), (2 REGEXP 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 OR 3, 2 REGEXP (3 OR 3), (2 REGEXP 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 XOR 3, 2 REGEXP (3 XOR 3), (2 REGEXP 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 XOR 3, 2 REGEXP (3 XOR 3), (2 REGEXP 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 AND 2, 2 REGEXP (2 AND 2), (2 REGEXP 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 AND 2, 2 REGEXP (2 AND 2), (2 REGEXP 2) AND 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 && 2, 2 REGEXP (2 && 2), (2 REGEXP 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 && 2, 2 REGEXP (2 && 2), (2 REGEXP 2) && 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 = 1, 2 REGEXP (2 = 1), (2 REGEXP 2) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 = 1, 2 REGEXP (2 = 1), (2 REGEXP 2) = 1 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 <=> 1, 2 REGEXP (2 <=> 1), (2 REGEXP 2) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 <=> 1, 2 REGEXP (2 <=> 1), (2 REGEXP 2) <=> 1 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 >= 1, 2 REGEXP (2 >= 1), (2 REGEXP 2) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 >= 1, 2 REGEXP (2 >= 1), (2 REGEXP 2) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 <= 3, 2 REGEXP (3 <= 3), (2 REGEXP 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 <= 3, 2 REGEXP (3 <= 3), (2 REGEXP 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 < 3, 2 REGEXP (3 < 3), (2 REGEXP 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 < 3, 2 REGEXP (3 < 3), (2 REGEXP 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 <> 3, 2 REGEXP (3 <> 3), (2 REGEXP 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 <> 3, 2 REGEXP (3 <> 3), (2 REGEXP 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 > 0, 2 REGEXP (2 > 0), (2 REGEXP 2) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 > 0, 2 REGEXP (2 > 0), (2 REGEXP 2) > 0 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 != 3, 2 REGEXP (3 != 3), (2 REGEXP 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 != 3, 2 REGEXP (3 != 3), (2 REGEXP 3) != 3 union select * from v1;
+
+create or replace view v1 as select 1 REGEXP 3 LIKE 3, 1 REGEXP (3 LIKE 3), (1 REGEXP 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 REGEXP 3 LIKE 3, 1 REGEXP (3 LIKE 3), (1 REGEXP 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 1 REGEXP 3 REGEXP 3, 1 REGEXP (3 REGEXP 3), (1 REGEXP 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 REGEXP 3 REGEXP 3, 1 REGEXP (3 REGEXP 3), (1 REGEXP 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 | 3, 2 REGEXP (3 | 3), (2 REGEXP 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 | 3, 2 REGEXP (3 | 3), (2 REGEXP 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 & 2, 2 REGEXP (2 & 2), (2 REGEXP 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 & 2, 2 REGEXP (2 & 2), (2 REGEXP 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 << 2, 2 REGEXP (2 << 2), (2 REGEXP 2) << 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 << 2, 2 REGEXP (2 << 2), (2 REGEXP 2) << 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 4 >> 1, 2 REGEXP (4 >> 1), (2 REGEXP 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 4 >> 1, 2 REGEXP (4 >> 1), (2 REGEXP 4) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP '2000-01-01' +INTERVAL 1 DAY, 2 REGEXP ('2000-01-01' +INTERVAL 1 DAY), (2 REGEXP '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP '2000-01-01' +INTERVAL 1 DAY, 2 REGEXP ('2000-01-01' +INTERVAL 1 DAY), (2 REGEXP '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 + 3, 2 REGEXP (3 + 3), (2 REGEXP 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 + 3, 2 REGEXP (3 + 3), (2 REGEXP 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 - 3, 2 REGEXP (3 - 3), (2 REGEXP 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 - 3, 2 REGEXP (3 - 3), (2 REGEXP 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 * 2, 2 REGEXP (2 * 2), (2 REGEXP 2) * 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 * 2, 2 REGEXP (2 * 2), (2 REGEXP 2) * 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 / 2, 2 REGEXP (2 / 2), (2 REGEXP 2) / 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 / 2, 2 REGEXP (2 / 2), (2 REGEXP 2) / 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 4 DIV 2, 2 REGEXP (4 DIV 2), (2 REGEXP 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 4 DIV 2, 2 REGEXP (4 DIV 2), (2 REGEXP 4) DIV 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 MOD 2, 2 REGEXP (2 MOD 2), (2 REGEXP 2) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 MOD 2, 2 REGEXP (2 MOD 2), (2 REGEXP 2) MOD 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 % 2, 2 REGEXP (2 % 2), (2 REGEXP 2) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 % 2, 2 REGEXP (2 % 2), (2 REGEXP 2) % 2 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 ^ 3, 2 REGEXP (3 ^ 3), (2 REGEXP 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 ^ 3, 2 REGEXP (3 ^ 3), (2 REGEXP 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 2 BETWEEN 1 AND 3, 2 REGEXP (2 BETWEEN 1 AND 3), (2 REGEXP 2) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 2 BETWEEN 1 AND 3, 2 REGEXP (2 BETWEEN 1 AND 3), (2 REGEXP 2) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 IS FALSE, 2 | (3 IS FALSE), (2 | 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 IS FALSE, 2 | (3 IS FALSE), (2 | 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 | 3 COLLATE latin1_bin), charset(2 | (3 COLLATE latin1_bin)), charset((2 | 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 | 3 COLLATE latin1_bin), charset(2 | (3 COLLATE latin1_bin)), charset((2 | 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 | 3 IN (0,1), 2 | (3 IN (0,1)), (2 | 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 IN (0,1), 2 | (3 IN (0,1)), (2 | 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 | 3 OR 3, 2 | (3 OR 3), (2 | 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 OR 3, 2 | (3 OR 3), (2 | 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 XOR 3, 2 | (3 XOR 3), (2 | 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 XOR 3, 2 | (3 XOR 3), (2 | 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 AND 3, 2 | (3 AND 3), (2 | 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 AND 3, 2 | (3 AND 3), (2 | 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 && 3, 2 | (3 && 3), (2 | 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 && 3, 2 | (3 && 3), (2 | 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 = 3, 2 | (3 = 3), (2 | 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 = 3, 2 | (3 = 3), (2 | 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 <=> 3, 2 | (3 <=> 3), (2 | 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 <=> 3, 2 | (3 <=> 3), (2 | 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 >= 3, 2 | (3 >= 3), (2 | 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 >= 3, 2 | (3 >= 3), (2 | 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 <= 3, 2 | (3 <= 3), (2 | 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 <= 3, 2 | (3 <= 3), (2 | 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 < 3, 2 | (3 < 3), (2 | 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 < 3, 2 | (3 < 3), (2 | 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 <> 3, 2 | (3 <> 3), (2 | 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 <> 3, 2 | (3 <> 3), (2 | 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 > 3, 2 | (3 > 3), (2 | 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 > 3, 2 | (3 > 3), (2 | 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 != 3, 2 | (3 != 3), (2 | 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 != 3, 2 | (3 != 3), (2 | 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 LIKE 3, 2 | (3 LIKE 3), (2 | 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 LIKE 3, 2 | (3 LIKE 3), (2 | 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 REGEXP 3, 2 | (3 REGEXP 3), (2 | 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 REGEXP 3, 2 | (3 REGEXP 3), (2 | 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 | 0 & 0, 2 | (0 & 0), (2 | 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 0 & 0, 2 | (0 & 0), (2 | 0) & 0 union select * from v1;
+
+create or replace view v1 as select 2 | 3 << 3, 2 | (3 << 3), (2 | 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 << 3, 2 | (3 << 3), (2 | 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 >> 3, 2 | (3 >> 3), (2 | 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 >> 3, 2 | (3 >> 3), (2 | 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 | '2000-01-01' +INTERVAL 1 DAY, 2 | ('2000-01-01' +INTERVAL 1 DAY), (2 | '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | '2000-01-01' +INTERVAL 1 DAY, 2 | ('2000-01-01' +INTERVAL 1 DAY), (2 | '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 | 1 + 1, 2 | (1 + 1), (2 | 1) + 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 1 + 1, 2 | (1 + 1), (2 | 1) + 1 union select * from v1;
+
+create or replace view v1 as select 2 | 3 - 3, 2 | (3 - 3), (2 | 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 - 3, 2 | (3 - 3), (2 | 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 * 3, 2 | (3 * 3), (2 | 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 * 3, 2 | (3 * 3), (2 | 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 / 3, 2 | (3 / 3), (2 | 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 / 3, 2 | (3 / 3), (2 | 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 DIV 3, 2 | (3 DIV 3), (2 | 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 DIV 3, 2 | (3 DIV 3), (2 | 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 MOD 3, 2 | (3 MOD 3), (2 | 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 MOD 3, 2 | (3 MOD 3), (2 | 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 % 3, 2 | (3 % 3), (2 | 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 % 3, 2 | (3 % 3), (2 | 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 ^ 3, 2 | (3 ^ 3), (2 | 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 ^ 3, 2 | (3 ^ 3), (2 | 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 BETWEEN 1 AND 3, 2 | (3 BETWEEN 1 AND 3), (2 | 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 BETWEEN 1 AND 3, 2 | (3 BETWEEN 1 AND 3), (2 | 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 & 1 IS FALSE, 2 & (1 IS FALSE), (2 & 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 1 IS FALSE, 2 & (1 IS FALSE), (2 & 1) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 & 3 COLLATE latin1_bin), charset(2 & (3 COLLATE latin1_bin)), charset((2 & 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 & 3 COLLATE latin1_bin), charset(2 & (3 COLLATE latin1_bin)), charset((2 & 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 & 4 IN (0,1), 2 & (4 IN (0,1)), (2 & 4) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 4 IN (0,1), 2 & (4 IN (0,1)), (2 & 4) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 & 3 OR 3, 2 & (3 OR 3), (2 & 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 OR 3, 2 & (3 OR 3), (2 & 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 & 1 XOR 1, 2 & (1 XOR 1), (2 & 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 1 XOR 1, 2 & (1 XOR 1), (2 & 1) XOR 1 union select * from v1;
+
+create or replace view v1 as select 2 & 3 AND 3, 2 & (3 AND 3), (2 & 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 AND 3, 2 & (3 AND 3), (2 & 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 && 3, 2 & (3 && 3), (2 & 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 && 3, 2 & (3 && 3), (2 & 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 = 2, 2 & (3 = 2), (2 & 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 = 2, 2 & (3 = 2), (2 & 3) = 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 <=> 2, 2 & (3 <=> 2), (2 & 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 <=> 2, 2 & (3 <=> 2), (2 & 3) <=> 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 >= 2, 2 & (3 >= 2), (2 & 3) >= 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 >= 2, 2 & (3 >= 2), (2 & 3) >= 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 <= 3, 2 & (3 <= 3), (2 & 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 <= 3, 2 & (3 <= 3), (2 & 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 < 3, 2 & (3 < 3), (2 & 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 < 3, 2 & (3 < 3), (2 & 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 <> 3, 2 & (3 <> 3), (2 & 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 <> 3, 2 & (3 <> 3), (2 & 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 > 1, 2 & (3 > 1), (2 & 3) > 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 > 1, 2 & (3 > 1), (2 & 3) > 1 union select * from v1;
+
+create or replace view v1 as select 2 & 3 != 3, 2 & (3 != 3), (2 & 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 != 3, 2 & (3 != 3), (2 & 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 LIKE 2, 2 & (3 LIKE 2), (2 & 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 LIKE 2, 2 & (3 LIKE 2), (2 & 3) LIKE 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 REGEXP 2, 2 & (3 REGEXP 2), (2 & 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 REGEXP 2, 2 & (3 REGEXP 2), (2 & 3) REGEXP 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 | 3, 2 & (3 | 3), (2 & 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 | 3, 2 & (3 | 3), (2 & 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 << 3, 2 & (3 << 3), (2 & 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 << 3, 2 & (3 << 3), (2 & 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 >> 1, 2 & (3 >> 1), (2 & 3) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 >> 1, 2 & (3 >> 1), (2 & 3) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 & '2000-01-01' +INTERVAL 1 DAY, 2 & ('2000-01-01' +INTERVAL 1 DAY), (2 & '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & '2000-01-01' +INTERVAL 1 DAY, 2 & ('2000-01-01' +INTERVAL 1 DAY), (2 & '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 & 3 + 3, 2 & (3 + 3), (2 & 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 + 3, 2 & (3 + 3), (2 & 3) + 3 union select * from v1;
+
+create or replace view v1 as select 6 & 4 - 3, 6 & (4 - 3), (6 & 4) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 6 & 4 - 3, 6 & (4 - 3), (6 & 4) - 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 * 3, 2 & (3 * 3), (2 & 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 * 3, 2 & (3 * 3), (2 & 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 / 3, 2 & (3 / 3), (2 & 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 / 3, 2 & (3 / 3), (2 & 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 DIV 2, 2 & (3 DIV 2), (2 & 3) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 DIV 2, 2 & (3 DIV 2), (2 & 3) DIV 2 union select * from v1;
+
+create or replace view v1 as select 2 & 3 MOD 3, 2 & (3 MOD 3), (2 & 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 MOD 3, 2 & (3 MOD 3), (2 & 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 % 3, 2 & (3 % 3), (2 & 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 % 3, 2 & (3 % 3), (2 & 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 ^ 3, 2 & (3 ^ 3), (2 & 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 ^ 3, 2 & (3 ^ 3), (2 & 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 BETWEEN 1 AND 3, 2 & (3 BETWEEN 1 AND 3), (2 & 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 BETWEEN 1 AND 3, 2 & (3 BETWEEN 1 AND 3), (2 & 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 IS FALSE, 2 << (3 IS FALSE), (2 << 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 IS FALSE, 2 << (3 IS FALSE), (2 << 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 << 3 COLLATE latin1_bin), charset(2 << (3 COLLATE latin1_bin)), charset((2 << 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 << 3 COLLATE latin1_bin), charset(2 << (3 COLLATE latin1_bin)), charset((2 << 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 << 3 IN (0,1), 2 << (3 IN (0,1)), (2 << 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 IN (0,1), 2 << (3 IN (0,1)), (2 << 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 << 3 OR 3, 2 << (3 OR 3), (2 << 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 OR 3, 2 << (3 OR 3), (2 << 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 XOR 3, 2 << (3 XOR 3), (2 << 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 XOR 3, 2 << (3 XOR 3), (2 << 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 AND 3, 2 << (3 AND 3), (2 << 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 AND 3, 2 << (3 AND 3), (2 << 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 && 3, 2 << (3 && 3), (2 << 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 && 3, 2 << (3 && 3), (2 << 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 = 3, 2 << (3 = 3), (2 << 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 = 3, 2 << (3 = 3), (2 << 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 <=> 3, 2 << (3 <=> 3), (2 << 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 <=> 3, 2 << (3 <=> 3), (2 << 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 >= 3, 2 << (3 >= 3), (2 << 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 >= 3, 2 << (3 >= 3), (2 << 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 <= 3, 2 << (3 <= 3), (2 << 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 <= 3, 2 << (3 <= 3), (2 << 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 < 3, 2 << (3 < 3), (2 << 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 < 3, 2 << (3 < 3), (2 << 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 <> 3, 2 << (3 <> 3), (2 << 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 <> 3, 2 << (3 <> 3), (2 << 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 > 3, 2 << (3 > 3), (2 << 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 > 3, 2 << (3 > 3), (2 << 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 != 3, 2 << (3 != 3), (2 << 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 != 3, 2 << (3 != 3), (2 << 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 LIKE 3, 2 << (3 LIKE 3), (2 << 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 LIKE 3, 2 << (3 LIKE 3), (2 << 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 REGEXP 3, 2 << (3 REGEXP 3), (2 << 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 REGEXP 3, 2 << (3 REGEXP 3), (2 << 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 | 3, 2 << (3 | 3), (2 << 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 | 3, 2 << (3 | 3), (2 << 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 & 3, 2 << (3 & 3), (2 << 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 & 3, 2 << (3 & 3), (2 << 3) & 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 << 3, 2 << (3 << 3), (2 << 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 << 3, 2 << (3 << 3), (2 << 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 << 2 >> 3, 2 << (2 >> 3), (2 << 2) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 2 >> 3, 2 << (2 >> 3), (2 << 2) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 << '2000-01-01' +INTERVAL 1 DAY, 2 << ('2000-01-01' +INTERVAL 1 DAY), (2 << '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << '2000-01-01' +INTERVAL 1 DAY, 2 << ('2000-01-01' +INTERVAL 1 DAY), (2 << '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 << 3 + 3, 2 << (3 + 3), (2 << 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 + 3, 2 << (3 + 3), (2 << 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 - 3, 2 << (3 - 3), (2 << 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 - 3, 2 << (3 - 3), (2 << 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 * 3, 2 << (3 * 3), (2 << 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 * 3, 2 << (3 * 3), (2 << 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 / 3, 2 << (3 / 3), (2 << 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 / 3, 2 << (3 / 3), (2 << 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 DIV 3, 2 << (3 DIV 3), (2 << 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 DIV 3, 2 << (3 DIV 3), (2 << 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 MOD 3, 2 << (3 MOD 3), (2 << 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 MOD 3, 2 << (3 MOD 3), (2 << 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 % 3, 2 << (3 % 3), (2 << 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 % 3, 2 << (3 % 3), (2 << 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 ^ 3, 2 << (3 ^ 3), (2 << 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 ^ 3, 2 << (3 ^ 3), (2 << 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 BETWEEN 1 AND 3, 2 << (3 BETWEEN 1 AND 3), (2 << 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 BETWEEN 1 AND 3, 2 << (3 BETWEEN 1 AND 3), (2 << 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 IS FALSE, 2 >> (3 IS FALSE), (2 >> 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 IS FALSE, 2 >> (3 IS FALSE), (2 >> 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 >> 3 COLLATE latin1_bin), charset(2 >> (3 COLLATE latin1_bin)), charset((2 >> 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 >> 3 COLLATE latin1_bin), charset(2 >> (3 COLLATE latin1_bin)), charset((2 >> 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 >> 3 IN (0,1), 2 >> (3 IN (0,1)), (2 >> 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 IN (0,1), 2 >> (3 IN (0,1)), (2 >> 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 >> 3 OR 0, 2 >> (3 OR 0), (2 >> 3) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 OR 0, 2 >> (3 OR 0), (2 >> 3) OR 0 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 XOR 3, 2 >> (3 XOR 3), (2 >> 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 XOR 3, 2 >> (3 XOR 3), (2 >> 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 AND 3, 2 >> (3 AND 3), (2 >> 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 AND 3, 2 >> (3 AND 3), (2 >> 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 && 3, 2 >> (3 && 3), (2 >> 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 && 3, 2 >> (3 && 3), (2 >> 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 = 3, 2 >> (3 = 3), (2 >> 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 = 3, 2 >> (3 = 3), (2 >> 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 <=> 3, 2 >> (3 <=> 3), (2 >> 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 <=> 3, 2 >> (3 <=> 3), (2 >> 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 >= 3, 2 >> (3 >= 3), (2 >> 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 >= 3, 2 >> (3 >= 3), (2 >> 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 <= 0, 2 >> (3 <= 0), (2 >> 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 <= 0, 2 >> (3 <= 0), (2 >> 3) <= 0 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 < 3, 2 >> (3 < 3), (2 >> 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 < 3, 2 >> (3 < 3), (2 >> 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 <> 3, 2 >> (3 <> 3), (2 >> 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 <> 3, 2 >> (3 <> 3), (2 >> 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 > 3, 2 >> (3 > 3), (2 >> 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 > 3, 2 >> (3 > 3), (2 >> 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 != 3, 2 >> (3 != 3), (2 >> 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 != 3, 2 >> (3 != 3), (2 >> 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 LIKE 3, 2 >> (3 LIKE 3), (2 >> 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 LIKE 3, 2 >> (3 LIKE 3), (2 >> 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 REGEXP 3, 2 >> (3 REGEXP 3), (2 >> 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 REGEXP 3, 2 >> (3 REGEXP 3), (2 >> 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 | 3, 2 >> (3 | 3), (2 >> 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 | 3, 2 >> (3 | 3), (2 >> 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 & 1, 2 >> (3 & 1), (2 >> 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 & 1, 2 >> (3 & 1), (2 >> 3) & 1 union select * from v1;
+
+create or replace view v1 as select 2 >> 1 << 3, 2 >> (1 << 3), (2 >> 1) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 1 << 3, 2 >> (1 << 3), (2 >> 1) << 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 >> 3, 2 >> (3 >> 3), (2 >> 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 >> 3, 2 >> (3 >> 3), (2 >> 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 >> '2000-01-01' +INTERVAL 1 DAY, 2 >> ('2000-01-01' +INTERVAL 1 DAY), (2 >> '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> '2000-01-01' +INTERVAL 1 DAY, 2 >> ('2000-01-01' +INTERVAL 1 DAY), (2 >> '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 >> 3 + 3, 2 >> (3 + 3), (2 >> 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 + 3, 2 >> (3 + 3), (2 >> 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 1 - 1, 2 >> (1 - 1), (2 >> 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 1 - 1, 2 >> (1 - 1), (2 >> 1) - 1 union select * from v1;
+
+create or replace view v1 as select 2 >> 1 * 3, 2 >> (1 * 3), (2 >> 1) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 1 * 3, 2 >> (1 * 3), (2 >> 1) * 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 / 3, 2 >> (3 / 3), (2 >> 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 / 3, 2 >> (3 / 3), (2 >> 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 DIV 3, 2 >> (3 DIV 3), (2 >> 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 DIV 3, 2 >> (3 DIV 3), (2 >> 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 MOD 3, 2 >> (3 MOD 3), (2 >> 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 MOD 3, 2 >> (3 MOD 3), (2 >> 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 % 3, 2 >> (3 % 3), (2 >> 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 % 3, 2 >> (3 % 3), (2 >> 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 ^ 3, 2 >> (3 ^ 3), (2 >> 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 ^ 3, 2 >> (3 ^ 3), (2 >> 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 BETWEEN 1 AND 3, 2 >> (3 BETWEEN 1 AND 3), (2 >> 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 BETWEEN 1 AND 3, 2 >> (3 BETWEEN 1 AND 3), (2 >> 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 IS FALSE, 2 + (3 IS FALSE), (2 + 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 IS FALSE, 2 + (3 IS FALSE), (2 + 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 + 3 COLLATE latin1_bin), charset(2 + (3 COLLATE latin1_bin)), charset((2 + 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 + 3 COLLATE latin1_bin), charset(2 + (3 COLLATE latin1_bin)), charset((2 + 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 + 3 IN (0,1), 2 + (3 IN (0,1)), (2 + 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 IN (0,1), 2 + (3 IN (0,1)), (2 + 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 + 3 OR 3, 2 + (3 OR 3), (2 + 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 OR 3, 2 + (3 OR 3), (2 + 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 XOR 3, 2 + (3 XOR 3), (2 + 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 XOR 3, 2 + (3 XOR 3), (2 + 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 AND 3, 2 + (3 AND 3), (2 + 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 AND 3, 2 + (3 AND 3), (2 + 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 && 3, 2 + (3 && 3), (2 + 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 && 3, 2 + (3 && 3), (2 + 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 = 3, 2 + (3 = 3), (2 + 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 = 3, 2 + (3 = 3), (2 + 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 <=> 3, 2 + (3 <=> 3), (2 + 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 <=> 3, 2 + (3 <=> 3), (2 + 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 >= 3, 2 + (3 >= 3), (2 + 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 >= 3, 2 + (3 >= 3), (2 + 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 <= 3, 2 + (3 <= 3), (2 + 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 <= 3, 2 + (3 <= 3), (2 + 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 < 3, 2 + (3 < 3), (2 + 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 < 3, 2 + (3 < 3), (2 + 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 <> 3, 2 + (3 <> 3), (2 + 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 <> 3, 2 + (3 <> 3), (2 + 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 > 3, 2 + (3 > 3), (2 + 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 > 3, 2 + (3 > 3), (2 + 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 != 3, 2 + (3 != 3), (2 + 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 != 3, 2 + (3 != 3), (2 + 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 LIKE 3, 2 + (3 LIKE 3), (2 + 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 LIKE 3, 2 + (3 LIKE 3), (2 + 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 REGEXP 3, 2 + (3 REGEXP 3), (2 + 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 REGEXP 3, 2 + (3 REGEXP 3), (2 + 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 | 3, 2 + (3 | 3), (2 + 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 | 3, 2 + (3 | 3), (2 + 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 & 3, 2 + (3 & 3), (2 + 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 & 3, 2 + (3 & 3), (2 + 3) & 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 << 3, 2 + (3 << 3), (2 + 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 << 3, 2 + (3 << 3), (2 + 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 >> 3, 2 + (3 >> 3), (2 + 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 >> 3, 2 + (3 >> 3), (2 + 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 + '2000-01-01' +INTERVAL 1 DAY, 2 + ('2000-01-01' +INTERVAL 1 DAY), (2 + '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + '2000-01-01' +INTERVAL 1 DAY, 2 + ('2000-01-01' +INTERVAL 1 DAY), (2 + '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 + 3 * 3, 2 + (3 * 3), (2 + 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 * 3, 2 + (3 * 3), (2 + 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 / 3, 2 + (3 / 3), (2 + 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 / 3, 2 + (3 / 3), (2 + 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 DIV 3, 2 + (3 DIV 3), (2 + 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 DIV 3, 2 + (3 DIV 3), (2 + 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 + 1 MOD 3, 2 + (1 MOD 3), (2 + 1) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 1 MOD 3, 2 + (1 MOD 3), (2 + 1) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 + 1 % 3, 2 + (1 % 3), (2 + 1) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 1 % 3, 2 + (1 % 3), (2 + 1) % 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 ^ 3, 2 + (3 ^ 3), (2 + 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 ^ 3, 2 + (3 ^ 3), (2 + 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 + 3 BETWEEN 1 AND 3, 2 + (3 BETWEEN 1 AND 3), (2 + 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 BETWEEN 1 AND 3, 2 + (3 BETWEEN 1 AND 3), (2 + 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 IS FALSE, 2 - (3 IS FALSE), (2 - 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 IS FALSE, 2 - (3 IS FALSE), (2 - 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 - 3 COLLATE latin1_bin), charset(2 - (3 COLLATE latin1_bin)), charset((2 - 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 - 3 COLLATE latin1_bin), charset(2 - (3 COLLATE latin1_bin)), charset((2 - 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 - 3 IN (0,1), 2 - (3 IN (0,1)), (2 - 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 IN (0,1), 2 - (3 IN (0,1)), (2 - 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 - 2 OR 0, 2 - (2 OR 0), (2 - 2) OR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 2 OR 0, 2 - (2 OR 0), (2 - 2) OR 0 union select * from v1;
+
+create or replace view v1 as select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0 union select * from v1;
+
+create or replace view v1 as select 2 - 3 XOR 3, 2 - (3 XOR 3), (2 - 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 XOR 3, 2 - (3 XOR 3), (2 - 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 - 2 AND 2, 2 - (2 AND 2), (2 - 2) AND 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 2 AND 2, 2 - (2 AND 2), (2 - 2) AND 2 union select * from v1;
+
+create or replace view v1 as select 2 - 2 && 2, 2 - (2 && 2), (2 - 2) && 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 2 && 2, 2 - (2 && 2), (2 - 2) && 2 union select * from v1;
+
+create or replace view v1 as select 2 - 3 = 3, 2 - (3 = 3), (2 - 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 = 3, 2 - (3 = 3), (2 - 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 <=> 3, 2 - (3 <=> 3), (2 - 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 <=> 3, 2 - (3 <=> 3), (2 - 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 >= 3, 2 - (3 >= 3), (2 - 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 >= 3, 2 - (3 >= 3), (2 - 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 <= 2, 2 - (3 <= 2), (2 - 3) <= 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 <= 2, 2 - (3 <= 2), (2 - 3) <= 2 union select * from v1;
+
+create or replace view v1 as select 2 - 3 < 3, 2 - (3 < 3), (2 - 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 < 3, 2 - (3 < 3), (2 - 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 <> 3, 2 - (3 <> 3), (2 - 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 <> 3, 2 - (3 <> 3), (2 - 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 > 3, 2 - (3 > 3), (2 - 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 > 3, 2 - (3 > 3), (2 - 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 != 3, 2 - (3 != 3), (2 - 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 != 3, 2 - (3 != 3), (2 - 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 LIKE 3, 2 - (3 LIKE 3), (2 - 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 LIKE 3, 2 - (3 LIKE 3), (2 - 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 REGEXP 3, 2 - (3 REGEXP 3), (2 - 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 REGEXP 3, 2 - (3 REGEXP 3), (2 - 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 - 0 | 1, 2 - (0 | 1), (2 - 0) | 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 0 | 1, 2 - (0 | 1), (2 - 0) | 1 union select * from v1;
+
+create or replace view v1 as select 2 - 1 & 2, 2 - (1 & 2), (2 - 1) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 1 & 2, 2 - (1 & 2), (2 - 1) & 2 union select * from v1;
+
+create or replace view v1 as select 2 - 1 << 1, 2 - (1 << 1), (2 - 1) << 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 1 << 1, 2 - (1 << 1), (2 - 1) << 1 union select * from v1;
+
+create or replace view v1 as select 2 - 3 >> 3, 2 - (3 >> 3), (2 - 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 >> 3, 2 - (3 >> 3), (2 - 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 - '2000-01-01' +INTERVAL 1 DAY, 2 - ('2000-01-01' +INTERVAL 1 DAY), (2 - '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - '2000-01-01' +INTERVAL 1 DAY, 2 - ('2000-01-01' +INTERVAL 1 DAY), (2 - '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 - 3 + 3, 2 - (3 + 3), (2 - 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 + 3, 2 - (3 + 3), (2 - 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 - 3, 2 - (3 - 3), (2 - 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 - 3, 2 - (3 - 3), (2 - 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 * 3, 2 - (3 * 3), (2 - 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 * 3, 2 - (3 * 3), (2 - 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 / 3, 2 - (3 / 3), (2 - 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 / 3, 2 - (3 / 3), (2 - 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 DIV 3, 2 - (3 DIV 3), (2 - 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 DIV 3, 2 - (3 DIV 3), (2 - 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 MOD 3, 2 - (3 MOD 3), (2 - 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 MOD 3, 2 - (3 MOD 3), (2 - 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 % 3, 2 - (3 % 3), (2 - 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 % 3, 2 - (3 % 3), (2 - 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 ^ 3, 2 - (3 ^ 3), (2 - 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 ^ 3, 2 - (3 ^ 3), (2 - 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 - 3 BETWEEN 1 AND 3, 2 - (3 BETWEEN 1 AND 3), (2 - 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 BETWEEN 1 AND 3, 2 - (3 BETWEEN 1 AND 3), (2 - 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 * 0 IS FALSE, 2 * (0 IS FALSE), (2 * 0) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 0 IS FALSE, 2 * (0 IS FALSE), (2 * 0) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 * 3 COLLATE latin1_bin), charset(2 * (3 COLLATE latin1_bin)), charset((2 * 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 * 3 COLLATE latin1_bin), charset(2 * (3 COLLATE latin1_bin)), charset((2 * 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 * 0 IN (0,1), 2 * (0 IN (0,1)), (2 * 0) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 0 IN (0,1), 2 * (0 IN (0,1)), (2 * 0) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 * 3 OR 3, 2 * (3 OR 3), (2 * 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 OR 3, 2 * (3 OR 3), (2 * 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 XOR 0, 2 * (3 XOR 0), (2 * 3) XOR 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 XOR 0, 2 * (3 XOR 0), (2 * 3) XOR 0 union select * from v1;
+
+create or replace view v1 as select 2 * 3 AND 3, 2 * (3 AND 3), (2 * 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 AND 3, 2 * (3 AND 3), (2 * 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 && 3, 2 * (3 && 3), (2 * 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 && 3, 2 * (3 && 3), (2 * 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 = 3, 2 * (3 = 3), (2 * 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 = 3, 2 * (3 = 3), (2 * 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 <=> 3, 2 * (3 <=> 3), (2 * 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 <=> 3, 2 * (3 <=> 3), (2 * 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 >= 3, 2 * (3 >= 3), (2 * 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 >= 3, 2 * (3 >= 3), (2 * 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 <= 3, 2 * (3 <= 3), (2 * 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 <= 3, 2 * (3 <= 3), (2 * 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 * 0 < 3, 2 * (0 < 3), (2 * 0) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 0 < 3, 2 * (0 < 3), (2 * 0) < 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 <> 3, 2 * (3 <> 3), (2 * 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 <> 3, 2 * (3 <> 3), (2 * 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 > 3, 2 * (3 > 3), (2 * 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 > 3, 2 * (3 > 3), (2 * 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 != 3, 2 * (3 != 3), (2 * 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 != 3, 2 * (3 != 3), (2 * 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 LIKE 3, 2 * (3 LIKE 3), (2 * 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 LIKE 3, 2 * (3 LIKE 3), (2 * 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 REGEXP 3, 2 * (3 REGEXP 3), (2 * 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 REGEXP 3, 2 * (3 REGEXP 3), (2 * 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 | 3, 2 * (3 | 3), (2 * 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 | 3, 2 * (3 | 3), (2 * 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 & 3, 2 * (3 & 3), (2 * 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 & 3, 2 * (3 & 3), (2 * 3) & 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 >> 2, 2 * (3 >> 2), (2 * 3) >> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 >> 2, 2 * (3 >> 2), (2 * 3) >> 2 union select * from v1;
+
+create or replace view v1 as select 2 * '2000-01-01' +INTERVAL 1 DAY, 2 * ('2000-01-01' +INTERVAL 1 DAY), (2 * '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * '2000-01-01' +INTERVAL 1 DAY, 2 * ('2000-01-01' +INTERVAL 1 DAY), (2 * '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 * 3 + 3, 2 * (3 + 3), (2 * 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 + 3, 2 * (3 + 3), (2 * 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 - 3, 2 * (3 - 3), (2 * 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 - 3, 2 * (3 - 3), (2 * 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 DIV 2, 2 * (3 DIV 2), (2 * 3) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 DIV 2, 2 * (3 DIV 2), (2 * 3) DIV 2 union select * from v1;
+
+create or replace view v1 as select 2 * 3 MOD 2, 2 * (3 MOD 2), (2 * 3) MOD 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 MOD 2, 2 * (3 MOD 2), (2 * 3) MOD 2 union select * from v1;
+
+create or replace view v1 as select 2 * 3 % 2, 2 * (3 % 2), (2 * 3) % 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 % 2, 2 * (3 % 2), (2 * 3) % 2 union select * from v1;
+
+create or replace view v1 as select 2 * 3 ^ 3, 2 * (3 ^ 3), (2 * 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 ^ 3, 2 * (3 ^ 3), (2 * 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 * 3 BETWEEN 1 AND 3, 2 * (3 BETWEEN 1 AND 3), (2 * 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 BETWEEN 1 AND 3, 2 * (3 BETWEEN 1 AND 3), (2 * 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 IS FALSE, 2 / (3 IS FALSE), (2 / 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 IS FALSE, 2 / (3 IS FALSE), (2 / 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 / 3 COLLATE latin1_bin), charset(2 / (3 COLLATE latin1_bin)), charset((2 / 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 / 3 COLLATE latin1_bin), charset(2 / (3 COLLATE latin1_bin)), charset((2 / 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 / 3 IN (0,1), 2 / (3 IN (0,1)), (2 / 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 IN (0,1), 2 / (3 IN (0,1)), (2 / 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 / 3 OR 3, 2 / (3 OR 3), (2 / 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 OR 3, 2 / (3 OR 3), (2 / 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 XOR 3, 2 / (3 XOR 3), (2 / 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 XOR 3, 2 / (3 XOR 3), (2 / 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 AND 3, 2 / (3 AND 3), (2 / 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 AND 3, 2 / (3 AND 3), (2 / 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 && 3, 2 / (3 && 3), (2 / 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 && 3, 2 / (3 && 3), (2 / 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 = 3, 2 / (3 = 3), (2 / 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 = 3, 2 / (3 = 3), (2 / 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 <=> 3, 2 / (3 <=> 3), (2 / 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 <=> 3, 2 / (3 <=> 3), (2 / 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 >= 3, 2 / (3 >= 3), (2 / 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 >= 3, 2 / (3 >= 3), (2 / 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 <= 3, 2 / (3 <= 3), (2 / 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 <= 3, 2 / (3 <= 3), (2 / 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 < 3, 2 / (3 < 3), (2 / 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 < 3, 2 / (3 < 3), (2 / 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 <> 3, 2 / (3 <> 3), (2 / 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 <> 3, 2 / (3 <> 3), (2 / 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 > 3, 2 / (3 > 3), (2 / 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 > 3, 2 / (3 > 3), (2 / 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 != 3, 2 / (3 != 3), (2 / 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 != 3, 2 / (3 != 3), (2 / 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 LIKE 3, 2 / (3 LIKE 3), (2 / 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 LIKE 3, 2 / (3 LIKE 3), (2 / 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 REGEXP 3, 2 / (3 REGEXP 3), (2 / 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 REGEXP 3, 2 / (3 REGEXP 3), (2 / 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 | 3, 2 / (3 | 3), (2 / 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 | 3, 2 / (3 | 3), (2 / 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 & 3, 2 / (3 & 3), (2 / 3) & 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 & 3, 2 / (3 & 3), (2 / 3) & 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 << 3, 2 / (3 << 3), (2 / 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 << 3, 2 / (3 << 3), (2 / 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 >> 3, 2 / (3 >> 3), (2 / 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 >> 3, 2 / (3 >> 3), (2 / 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 / '2000-01-01' +INTERVAL 1 DAY, 2 / ('2000-01-01' +INTERVAL 1 DAY), (2 / '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / '2000-01-01' +INTERVAL 1 DAY, 2 / ('2000-01-01' +INTERVAL 1 DAY), (2 / '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 / 3 + 3, 2 / (3 + 3), (2 / 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 + 3, 2 / (3 + 3), (2 / 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 - 3, 2 / (3 - 3), (2 / 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 - 3, 2 / (3 - 3), (2 / 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 * 3, 2 / (3 * 3), (2 / 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 * 3, 2 / (3 * 3), (2 / 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 DIV 3, 2 / (3 DIV 3), (2 / 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 DIV 3, 2 / (3 DIV 3), (2 / 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 MOD 3, 2 / (3 MOD 3), (2 / 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 MOD 3, 2 / (3 MOD 3), (2 / 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 % 3, 2 / (3 % 3), (2 / 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 % 3, 2 / (3 % 3), (2 / 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 ^ 3, 2 / (3 ^ 3), (2 / 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 ^ 3, 2 / (3 ^ 3), (2 / 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 BETWEEN 1 AND 3, 2 / (3 BETWEEN 1 AND 3), (2 / 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 BETWEEN 1 AND 3, 2 / (3 BETWEEN 1 AND 3), (2 / 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 IS FALSE, 2 DIV (3 IS FALSE), (2 DIV 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 IS FALSE, 2 DIV (3 IS FALSE), (2 DIV 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 DIV 3 COLLATE latin1_bin), charset(2 DIV (3 COLLATE latin1_bin)), charset((2 DIV 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 DIV 3 COLLATE latin1_bin), charset(2 DIV (3 COLLATE latin1_bin)), charset((2 DIV 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 IN (0,1), 2 DIV (3 IN (0,1)), (2 DIV 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 IN (0,1), 2 DIV (3 IN (0,1)), (2 DIV 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 OR 3, 2 DIV (3 OR 3), (2 DIV 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 OR 3, 2 DIV (3 OR 3), (2 DIV 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 XOR 3, 2 DIV (3 XOR 3), (2 DIV 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 XOR 3, 2 DIV (3 XOR 3), (2 DIV 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 AND 3, 2 DIV (3 AND 3), (2 DIV 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 AND 3, 2 DIV (3 AND 3), (2 DIV 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 && 3, 2 DIV (3 && 3), (2 DIV 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 && 3, 2 DIV (3 && 3), (2 DIV 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 = 3, 2 DIV (3 = 3), (2 DIV 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 = 3, 2 DIV (3 = 3), (2 DIV 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 <=> 3, 2 DIV (3 <=> 3), (2 DIV 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 <=> 3, 2 DIV (3 <=> 3), (2 DIV 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 >= 3, 2 DIV (3 >= 3), (2 DIV 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 >= 3, 2 DIV (3 >= 3), (2 DIV 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 <= 3, 2 DIV (3 <= 3), (2 DIV 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 <= 3, 2 DIV (3 <= 3), (2 DIV 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 < 3, 2 DIV (3 < 3), (2 DIV 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 < 3, 2 DIV (3 < 3), (2 DIV 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 <> 3, 2 DIV (3 <> 3), (2 DIV 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 <> 3, 2 DIV (3 <> 3), (2 DIV 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 > 3, 2 DIV (3 > 3), (2 DIV 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 > 3, 2 DIV (3 > 3), (2 DIV 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 != 3, 2 DIV (3 != 3), (2 DIV 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 != 3, 2 DIV (3 != 3), (2 DIV 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 LIKE 3, 2 DIV (3 LIKE 3), (2 DIV 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 LIKE 3, 2 DIV (3 LIKE 3), (2 DIV 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 REGEXP 3, 2 DIV (3 REGEXP 3), (2 DIV 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 REGEXP 3, 2 DIV (3 REGEXP 3), (2 DIV 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 | 3, 2 DIV (3 | 3), (2 DIV 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 | 3, 2 DIV (3 | 3), (2 DIV 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 & 1, 2 DIV (3 & 1), (2 DIV 3) & 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 & 1, 2 DIV (3 & 1), (2 DIV 3) & 1 union select * from v1;
+
+create or replace view v1 as select 4 DIV 3 << 3, 4 DIV (3 << 3), (4 DIV 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 DIV 3 << 3, 4 DIV (3 << 3), (4 DIV 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 >> 3, 2 DIV (3 >> 3), (2 DIV 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 >> 3, 2 DIV (3 >> 3), (2 DIV 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV '2000-01-01' +INTERVAL 1 DAY, 2 DIV ('2000-01-01' +INTERVAL 1 DAY), (2 DIV '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV '2000-01-01' +INTERVAL 1 DAY, 2 DIV ('2000-01-01' +INTERVAL 1 DAY), (2 DIV '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 + 3, 2 DIV (3 + 3), (2 DIV 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 + 3, 2 DIV (3 + 3), (2 DIV 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 - 3, 2 DIV (3 - 3), (2 DIV 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 - 3, 2 DIV (3 - 3), (2 DIV 3) - 3 union select * from v1;
+
+create or replace view v1 as select 4 DIV 3 * 3, 4 DIV (3 * 3), (4 DIV 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 4 DIV 3 * 3, 4 DIV (3 * 3), (4 DIV 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 / 3, 2 DIV (3 / 3), (2 DIV 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 / 3, 2 DIV (3 / 3), (2 DIV 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 DIV 3, 2 DIV (3 DIV 3), (2 DIV 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 DIV 3, 2 DIV (3 DIV 3), (2 DIV 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 MOD 3, 2 DIV (3 MOD 3), (2 DIV 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 MOD 3, 2 DIV (3 MOD 3), (2 DIV 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 % 3, 2 DIV (3 % 3), (2 DIV 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 % 3, 2 DIV (3 % 3), (2 DIV 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 ^ 3, 2 DIV (3 ^ 3), (2 DIV 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 ^ 3, 2 DIV (3 ^ 3), (2 DIV 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 BETWEEN 1 AND 3, 2 DIV (3 BETWEEN 1 AND 3), (2 DIV 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 BETWEEN 1 AND 3, 2 DIV (3 BETWEEN 1 AND 3), (2 DIV 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 IS FALSE, 2 MOD (3 IS FALSE), (2 MOD 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 IS FALSE, 2 MOD (3 IS FALSE), (2 MOD 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 MOD 3 COLLATE latin1_bin), charset(2 MOD (3 COLLATE latin1_bin)), charset((2 MOD 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 MOD 3 COLLATE latin1_bin), charset(2 MOD (3 COLLATE latin1_bin)), charset((2 MOD 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 IN (0,1), 2 MOD (3 IN (0,1)), (2 MOD 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 IN (0,1), 2 MOD (3 IN (0,1)), (2 MOD 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 OR 3, 2 MOD (3 OR 3), (2 MOD 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 OR 3, 2 MOD (3 OR 3), (2 MOD 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 XOR 3, 2 MOD (3 XOR 3), (2 MOD 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 XOR 3, 2 MOD (3 XOR 3), (2 MOD 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 AND 3, 2 MOD (3 AND 3), (2 MOD 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 AND 3, 2 MOD (3 AND 3), (2 MOD 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 && 3, 2 MOD (3 && 3), (2 MOD 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 && 3, 2 MOD (3 && 3), (2 MOD 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 = 2, 2 MOD (3 = 2), (2 MOD 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 = 2, 2 MOD (3 = 2), (2 MOD 3) = 2 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 <=> 2, 2 MOD (3 <=> 2), (2 MOD 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 <=> 2, 2 MOD (3 <=> 2), (2 MOD 3) <=> 2 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 >= 1, 2 MOD (3 >= 1), (2 MOD 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 >= 1, 2 MOD (3 >= 1), (2 MOD 3) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 <= 3, 2 MOD (3 <= 3), (2 MOD 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 <= 3, 2 MOD (3 <= 3), (2 MOD 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 < 3, 2 MOD (3 < 3), (2 MOD 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 < 3, 2 MOD (3 < 3), (2 MOD 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 <> 3, 2 MOD (3 <> 3), (2 MOD 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 <> 3, 2 MOD (3 <> 3), (2 MOD 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 > 3, 2 MOD (3 > 3), (2 MOD 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 > 3, 2 MOD (3 > 3), (2 MOD 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 != 3, 2 MOD (3 != 3), (2 MOD 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 != 3, 2 MOD (3 != 3), (2 MOD 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 LIKE 2, 2 MOD (3 LIKE 2), (2 MOD 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 LIKE 2, 2 MOD (3 LIKE 2), (2 MOD 3) LIKE 2 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 REGEXP 2, 2 MOD (3 REGEXP 2), (2 MOD 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 REGEXP 2, 2 MOD (3 REGEXP 2), (2 MOD 3) REGEXP 2 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 | 3, 2 MOD (3 | 3), (2 MOD 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 | 3, 2 MOD (3 | 3), (2 MOD 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 4 & 4, 2 MOD (4 & 4), (2 MOD 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 4 & 4, 2 MOD (4 & 4), (2 MOD 4) & 4 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 << 3, 2 MOD (3 << 3), (2 MOD 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 << 3, 2 MOD (3 << 3), (2 MOD 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 >> 3, 2 MOD (3 >> 3), (2 MOD 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 >> 3, 2 MOD (3 >> 3), (2 MOD 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD '2000-01-01' +INTERVAL 1 DAY, 2 MOD ('2000-01-01' +INTERVAL 1 DAY), (2 MOD '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD '2000-01-01' +INTERVAL 1 DAY, 2 MOD ('2000-01-01' +INTERVAL 1 DAY), (2 MOD '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 + 3, 2 MOD (3 + 3), (2 MOD 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 + 3, 2 MOD (3 + 3), (2 MOD 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 - 3, 2 MOD (3 - 3), (2 MOD 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 - 3, 2 MOD (3 - 3), (2 MOD 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 * 3, 2 MOD (3 * 3), (2 MOD 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 * 3, 2 MOD (3 * 3), (2 MOD 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 / 3, 2 MOD (3 / 3), (2 MOD 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 / 3, 2 MOD (3 / 3), (2 MOD 3) / 3 union select * from v1;
+
+create or replace view v1 as select 3 MOD 4 DIV 3, 3 MOD (4 DIV 3), (3 MOD 4) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 MOD 4 DIV 3, 3 MOD (4 DIV 3), (3 MOD 4) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 MOD 3, 2 MOD (3 MOD 3), (2 MOD 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 MOD 3, 2 MOD (3 MOD 3), (2 MOD 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 % 3, 2 MOD (3 % 3), (2 MOD 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 % 3, 2 MOD (3 % 3), (2 MOD 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 ^ 3, 2 MOD (3 ^ 3), (2 MOD 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 ^ 3, 2 MOD (3 ^ 3), (2 MOD 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 BETWEEN 1 AND 3, 2 MOD (3 BETWEEN 1 AND 3), (2 MOD 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 BETWEEN 1 AND 3, 2 MOD (3 BETWEEN 1 AND 3), (2 MOD 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 IS FALSE, 2 % (3 IS FALSE), (2 % 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 IS FALSE, 2 % (3 IS FALSE), (2 % 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 % 3 COLLATE latin1_bin), charset(2 % (3 COLLATE latin1_bin)), charset((2 % 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 % 3 COLLATE latin1_bin), charset(2 % (3 COLLATE latin1_bin)), charset((2 % 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 % 3 IN (0,1), 2 % (3 IN (0,1)), (2 % 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 IN (0,1), 2 % (3 IN (0,1)), (2 % 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 % 3 OR 3, 2 % (3 OR 3), (2 % 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 OR 3, 2 % (3 OR 3), (2 % 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 XOR 3, 2 % (3 XOR 3), (2 % 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 XOR 3, 2 % (3 XOR 3), (2 % 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 AND 3, 2 % (3 AND 3), (2 % 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 AND 3, 2 % (3 AND 3), (2 % 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 && 3, 2 % (3 && 3), (2 % 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 && 3, 2 % (3 && 3), (2 % 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 = 2, 2 % (3 = 2), (2 % 3) = 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 = 2, 2 % (3 = 2), (2 % 3) = 2 union select * from v1;
+
+create or replace view v1 as select 2 % 3 <=> 2, 2 % (3 <=> 2), (2 % 3) <=> 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 <=> 2, 2 % (3 <=> 2), (2 % 3) <=> 2 union select * from v1;
+
+create or replace view v1 as select 2 % 3 >= 1, 2 % (3 >= 1), (2 % 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 >= 1, 2 % (3 >= 1), (2 % 3) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 % 3 <= 3, 2 % (3 <= 3), (2 % 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 <= 3, 2 % (3 <= 3), (2 % 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 < 3, 2 % (3 < 3), (2 % 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 < 3, 2 % (3 < 3), (2 % 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 <> 3, 2 % (3 <> 3), (2 % 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 <> 3, 2 % (3 <> 3), (2 % 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 > 3, 2 % (3 > 3), (2 % 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 > 3, 2 % (3 > 3), (2 % 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 != 3, 2 % (3 != 3), (2 % 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 != 3, 2 % (3 != 3), (2 % 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 LIKE 2, 2 % (3 LIKE 2), (2 % 3) LIKE 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 LIKE 2, 2 % (3 LIKE 2), (2 % 3) LIKE 2 union select * from v1;
+
+create or replace view v1 as select 2 % 3 REGEXP 2, 2 % (3 REGEXP 2), (2 % 3) REGEXP 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 REGEXP 2, 2 % (3 REGEXP 2), (2 % 3) REGEXP 2 union select * from v1;
+
+create or replace view v1 as select 2 % 3 | 3, 2 % (3 | 3), (2 % 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 | 3, 2 % (3 | 3), (2 % 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 % 4 & 4, 2 % (4 & 4), (2 % 4) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 4 & 4, 2 % (4 & 4), (2 % 4) & 4 union select * from v1;
+
+create or replace view v1 as select 2 % 3 << 3, 2 % (3 << 3), (2 % 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 << 3, 2 % (3 << 3), (2 % 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 >> 3, 2 % (3 >> 3), (2 % 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 >> 3, 2 % (3 >> 3), (2 % 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 % '2000-01-01' +INTERVAL 1 DAY, 2 % ('2000-01-01' +INTERVAL 1 DAY), (2 % '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % '2000-01-01' +INTERVAL 1 DAY, 2 % ('2000-01-01' +INTERVAL 1 DAY), (2 % '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 % 3 + 3, 2 % (3 + 3), (2 % 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 + 3, 2 % (3 + 3), (2 % 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 - 3, 2 % (3 - 3), (2 % 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 - 3, 2 % (3 - 3), (2 % 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 * 3, 2 % (3 * 3), (2 % 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 * 3, 2 % (3 * 3), (2 % 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 / 3, 2 % (3 / 3), (2 % 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 / 3, 2 % (3 / 3), (2 % 3) / 3 union select * from v1;
+
+create or replace view v1 as select 3 % 4 DIV 3, 3 % (4 DIV 3), (3 % 4) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 % 4 DIV 3, 3 % (4 DIV 3), (3 % 4) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 MOD 3, 2 % (3 MOD 3), (2 % 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 MOD 3, 2 % (3 MOD 3), (2 % 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 % 3, 2 % (3 % 3), (2 % 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 % 3, 2 % (3 % 3), (2 % 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 ^ 3, 2 % (3 ^ 3), (2 % 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 ^ 3, 2 % (3 ^ 3), (2 % 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 BETWEEN 1 AND 3, 2 % (3 BETWEEN 1 AND 3), (2 % 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 BETWEEN 1 AND 3, 2 % (3 BETWEEN 1 AND 3), (2 % 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 IS FALSE, 2 ^ (3 IS FALSE), (2 ^ 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 IS FALSE, 2 ^ (3 IS FALSE), (2 ^ 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 ^ 3 COLLATE latin1_bin), charset(2 ^ (3 COLLATE latin1_bin)), charset((2 ^ 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 ^ 3 COLLATE latin1_bin), charset(2 ^ (3 COLLATE latin1_bin)), charset((2 ^ 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 IN (0,1), 2 ^ (3 IN (0,1)), (2 ^ 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 IN (0,1), 2 ^ (3 IN (0,1)), (2 ^ 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 OR 3, 2 ^ (3 OR 3), (2 ^ 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 OR 3, 2 ^ (3 OR 3), (2 ^ 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 XOR 3, 2 ^ (3 XOR 3), (2 ^ 3) XOR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 XOR 3, 2 ^ (3 XOR 3), (2 ^ 3) XOR 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 AND 3, 2 ^ (3 AND 3), (2 ^ 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 AND 3, 2 ^ (3 AND 3), (2 ^ 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 && 3, 2 ^ (3 && 3), (2 ^ 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 && 3, 2 ^ (3 && 3), (2 ^ 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 = 3, 2 ^ (3 = 3), (2 ^ 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 = 3, 2 ^ (3 = 3), (2 ^ 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 <=> 3, 2 ^ (3 <=> 3), (2 ^ 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 <=> 3, 2 ^ (3 <=> 3), (2 ^ 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 >= 3, 2 ^ (3 >= 3), (2 ^ 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 >= 3, 2 ^ (3 >= 3), (2 ^ 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 <= 3, 2 ^ (3 <= 3), (2 ^ 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 <= 3, 2 ^ (3 <= 3), (2 ^ 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 < 3, 2 ^ (3 < 3), (2 ^ 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 < 3, 2 ^ (3 < 3), (2 ^ 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 <> 3, 2 ^ (3 <> 3), (2 ^ 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 <> 3, 2 ^ (3 <> 3), (2 ^ 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 > 3, 2 ^ (3 > 3), (2 ^ 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 > 3, 2 ^ (3 > 3), (2 ^ 3) > 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 != 3, 2 ^ (3 != 3), (2 ^ 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 != 3, 2 ^ (3 != 3), (2 ^ 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 LIKE 3, 2 ^ (3 LIKE 3), (2 ^ 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 LIKE 3, 2 ^ (3 LIKE 3), (2 ^ 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 REGEXP 3, 2 ^ (3 REGEXP 3), (2 ^ 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 REGEXP 3, 2 ^ (3 REGEXP 3), (2 ^ 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 | 3, 2 ^ (3 | 3), (2 ^ 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 | 3, 2 ^ (3 | 3), (2 ^ 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 0 & 0, 2 ^ (0 & 0), (2 ^ 0) & 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 0 & 0, 2 ^ (0 & 0), (2 ^ 0) & 0 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 << 3, 2 ^ (3 << 3), (2 ^ 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 << 3, 2 ^ (3 << 3), (2 ^ 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 >> 3, 2 ^ (3 >> 3), (2 ^ 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 >> 3, 2 ^ (3 >> 3), (2 ^ 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ '2000-01-01' +INTERVAL 1 DAY, 2 ^ ('2000-01-01' +INTERVAL 1 DAY), (2 ^ '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ '2000-01-01' +INTERVAL 1 DAY, 2 ^ ('2000-01-01' +INTERVAL 1 DAY), (2 ^ '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 + 1, 2 ^ (3 + 1), (2 ^ 3) + 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 + 1, 2 ^ (3 + 1), (2 ^ 3) + 1 union select * from v1;
+
+create or replace view v1 as select 5 ^ 1 - 1, 5 ^ (1 - 1), (5 ^ 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 5 ^ 1 - 1, 5 ^ (1 - 1), (5 ^ 1) - 1 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 * 3, 2 ^ (3 * 3), (2 ^ 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 * 3, 2 ^ (3 * 3), (2 ^ 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 / 3, 2 ^ (3 / 3), (2 ^ 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 / 3, 2 ^ (3 / 3), (2 ^ 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 DIV 3, 2 ^ (3 DIV 3), (2 ^ 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 DIV 3, 2 ^ (3 DIV 3), (2 ^ 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 MOD 3, 2 ^ (3 MOD 3), (2 ^ 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 MOD 3, 2 ^ (3 MOD 3), (2 ^ 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 % 3, 2 ^ (3 % 3), (2 ^ 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 % 3, 2 ^ (3 % 3), (2 ^ 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 BETWEEN 1 AND 3, 2 ^ (3 BETWEEN 1 AND 3), (2 ^ 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 BETWEEN 1 AND 3, 2 ^ (3 BETWEEN 1 AND 3), (2 ^ 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 1 IS FALSE, 2 BETWEEN 1 AND (1 IS FALSE), (2 BETWEEN 1 AND 1) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 1 IS FALSE, 2 BETWEEN 1 AND (1 IS FALSE), (2 BETWEEN 1 AND 1) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin), charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin)), charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 BETWEEN 1 AND 3 COLLATE latin1_bin), charset(2 BETWEEN 1 AND (3 COLLATE latin1_bin)), charset((2 BETWEEN 1 AND 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 IN (0,1), 2 BETWEEN 1 AND (3 IN (0,1)), (2 BETWEEN 1 AND 3) IN (0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 IN (0,1), 2 BETWEEN 1 AND (3 IN (0,1)), (2 BETWEEN 1 AND 3) IN (0,1) union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 OR 3, 2 BETWEEN 1 AND (3 OR 3), (2 BETWEEN 1 AND 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 OR 3, 2 BETWEEN 1 AND (3 OR 3), (2 BETWEEN 1 AND 3) OR 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 1 XOR 1, 2 BETWEEN 1 AND (1 XOR 1), (2 BETWEEN 1 AND 1) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 1 XOR 1, 2 BETWEEN 1 AND (1 XOR 1), (2 BETWEEN 1 AND 1) XOR 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 AND 3, 2 BETWEEN 1 AND (3 AND 3), (2 BETWEEN 1 AND 3) AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 AND 3, 2 BETWEEN 1 AND (3 AND 3), (2 BETWEEN 1 AND 3) AND 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 && 3, 2 BETWEEN 1 AND (3 && 3), (2 BETWEEN 1 AND 3) && 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 && 3, 2 BETWEEN 1 AND (3 && 3), (2 BETWEEN 1 AND 3) && 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 = 1, 2 BETWEEN 1 AND (3 = 1), (2 BETWEEN 1 AND 3) = 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 = 1, 2 BETWEEN 1 AND (3 = 1), (2 BETWEEN 1 AND 3) = 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <=> 1, 2 BETWEEN 1 AND (3 <=> 1), (2 BETWEEN 1 AND 3) <=> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 <=> 1, 2 BETWEEN 1 AND (3 <=> 1), (2 BETWEEN 1 AND 3) <=> 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 >= 1, 2 BETWEEN 1 AND (3 >= 1), (2 BETWEEN 1 AND 3) >= 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 >= 1, 2 BETWEEN 1 AND (3 >= 1), (2 BETWEEN 1 AND 3) >= 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <= 3, 2 BETWEEN 1 AND (3 <= 3), (2 BETWEEN 1 AND 3) <= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 <= 3, 2 BETWEEN 1 AND (3 <= 3), (2 BETWEEN 1 AND 3) <= 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 < 3, 2 BETWEEN 1 AND (3 < 3), (2 BETWEEN 1 AND 3) < 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 < 3, 2 BETWEEN 1 AND (3 < 3), (2 BETWEEN 1 AND 3) < 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 <> 3, 2 BETWEEN 1 AND (3 <> 3), (2 BETWEEN 1 AND 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 <> 3, 2 BETWEEN 1 AND (3 <> 3), (2 BETWEEN 1 AND 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 > 0, 2 BETWEEN 1 AND (3 > 0), (2 BETWEEN 1 AND 3) > 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 > 0, 2 BETWEEN 1 AND (3 > 0), (2 BETWEEN 1 AND 3) > 0 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 != 3, 2 BETWEEN 1 AND (3 != 3), (2 BETWEEN 1 AND 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 != 3, 2 BETWEEN 1 AND (3 != 3), (2 BETWEEN 1 AND 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 LIKE 1, 2 BETWEEN 1 AND (3 LIKE 1), (2 BETWEEN 1 AND 3) LIKE 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 LIKE 1, 2 BETWEEN 1 AND (3 LIKE 1), (2 BETWEEN 1 AND 3) LIKE 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 REGEXP 1, 2 BETWEEN 1 AND (3 REGEXP 1), (2 BETWEEN 1 AND 3) REGEXP 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 REGEXP 1, 2 BETWEEN 1 AND (3 REGEXP 1), (2 BETWEEN 1 AND 3) REGEXP 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 | 3, 2 BETWEEN 1 AND (3 | 3), (2 BETWEEN 1 AND 3) | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 | 3, 2 BETWEEN 1 AND (3 | 3), (2 BETWEEN 1 AND 3) | 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 2 & 2, 2 BETWEEN 1 AND (2 & 2), (2 BETWEEN 1 AND 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 2 & 2, 2 BETWEEN 1 AND (2 & 2), (2 BETWEEN 1 AND 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 << 3, 2 BETWEEN 1 AND (3 << 3), (2 BETWEEN 1 AND 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 << 3, 2 BETWEEN 1 AND (3 << 3), (2 BETWEEN 1 AND 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 4 >> 1, 2 BETWEEN 1 AND (4 >> 1), (2 BETWEEN 1 AND 4) >> 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 4 >> 1, 2 BETWEEN 1 AND (4 >> 1), (2 BETWEEN 1 AND 4) >> 1 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY, 2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY), (2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND '2000-01-01' +INTERVAL 1 DAY, 2 BETWEEN 1 AND ('2000-01-01' +INTERVAL 1 DAY), (2 BETWEEN 1 AND '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 + 3, 2 BETWEEN 1 AND (3 + 3), (2 BETWEEN 1 AND 3) + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 + 3, 2 BETWEEN 1 AND (3 + 3), (2 BETWEEN 1 AND 3) + 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 - 3, 2 BETWEEN 1 AND (3 - 3), (2 BETWEEN 1 AND 3) - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 - 3, 2 BETWEEN 1 AND (3 - 3), (2 BETWEEN 1 AND 3) - 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 * 3, 2 BETWEEN 1 AND (3 * 3), (2 BETWEEN 1 AND 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 * 3, 2 BETWEEN 1 AND (3 * 3), (2 BETWEEN 1 AND 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 / 3, 2 BETWEEN 1 AND (3 / 3), (2 BETWEEN 1 AND 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 / 3, 2 BETWEEN 1 AND (3 / 3), (2 BETWEEN 1 AND 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 4 DIV 2, 2 BETWEEN 1 AND (4 DIV 2), (2 BETWEEN 1 AND 4) DIV 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 4 DIV 2, 2 BETWEEN 1 AND (4 DIV 2), (2 BETWEEN 1 AND 4) DIV 2 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 MOD 3, 2 BETWEEN 1 AND (3 MOD 3), (2 BETWEEN 1 AND 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 MOD 3, 2 BETWEEN 1 AND (3 MOD 3), (2 BETWEEN 1 AND 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 % 3, 2 BETWEEN 1 AND (3 % 3), (2 BETWEEN 1 AND 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 % 3, 2 BETWEEN 1 AND (3 % 3), (2 BETWEEN 1 AND 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 ^ 3, 2 BETWEEN 1 AND (3 ^ 3), (2 BETWEEN 1 AND 3) ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 ^ 3, 2 BETWEEN 1 AND (3 ^ 3), (2 BETWEEN 1 AND 3) ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 BETWEEN 1 AND 3, 2 BETWEEN 1 AND (3 BETWEEN 1 AND 3), (2 BETWEEN 1 AND 3) BETWEEN 1 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 BETWEEN 1 AND 3, 2 BETWEEN 1 AND (3 BETWEEN 1 AND 3), (2 BETWEEN 1 AND 3) BETWEEN 1 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 IS FALSE, 2 LIKE 2 ESCAPE (3 IS FALSE), (2 LIKE 2 ESCAPE 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 IS FALSE, 2 LIKE 2 ESCAPE (3 IS FALSE), (2 LIKE 2 ESCAPE 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin), charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin)), charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 LIKE 1 ESCAPE 3 COLLATE latin1_bin), charset(2 LIKE 1 ESCAPE (3 COLLATE latin1_bin)), charset((2 LIKE 1 ESCAPE 3) COLLATE latin1_bin) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 IN(0,1), 2 LIKE 1 ESCAPE (3 IN(0,1)), (2 LIKE 1 ESCAPE 3) IN(0,1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 IN(0,1), 2 LIKE 1 ESCAPE (3 IN(0,1)), (2 LIKE 1 ESCAPE 3) IN(0,1) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 OR 4, 2 LIKE 1 ESCAPE (3 OR 4), (2 LIKE 1 ESCAPE 3) OR 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 OR 4, 2 LIKE 1 ESCAPE (3 OR 4), (2 LIKE 1 ESCAPE 3) OR 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 || 4, 2 LIKE 1 ESCAPE (3 || 4), (2 LIKE 1 ESCAPE 3) || 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 || 4, 2 LIKE 1 ESCAPE (3 || 4), (2 LIKE 1 ESCAPE 3) || 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 XOR 4, 2 LIKE 1 ESCAPE (3 XOR 4), (2 LIKE 1 ESCAPE 3) XOR 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 XOR 4, 2 LIKE 1 ESCAPE (3 XOR 4), (2 LIKE 1 ESCAPE 3) XOR 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 AND 0, 2 LIKE 2 ESCAPE (3 AND 0), (2 LIKE 2 ESCAPE 3) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 AND 0, 2 LIKE 2 ESCAPE (3 AND 0), (2 LIKE 2 ESCAPE 3) AND 0 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 && 0, 2 LIKE 2 ESCAPE (3 && 0), (2 LIKE 2 ESCAPE 3) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 && 0, 2 LIKE 2 ESCAPE (3 && 0), (2 LIKE 2 ESCAPE 3) && 0 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 = 4, 2 LIKE 2 ESCAPE (3 = 4), (2 LIKE 2 ESCAPE 3) = 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 = 4, 2 LIKE 2 ESCAPE (3 = 4), (2 LIKE 2 ESCAPE 3) = 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 <=> 4, 2 LIKE 2 ESCAPE (3 <=> 4), (2 LIKE 2 ESCAPE 3) <=> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 <=> 4, 2 LIKE 2 ESCAPE (3 <=> 4), (2 LIKE 2 ESCAPE 3) <=> 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 >= 4, 2 LIKE 2 ESCAPE (3 >= 4), (2 LIKE 2 ESCAPE 3) >= 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 >= 4, 2 LIKE 2 ESCAPE (3 >= 4), (2 LIKE 2 ESCAPE 3) >= 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 <= 4, 2 LIKE 1 ESCAPE (3 <= 4), (2 LIKE 1 ESCAPE 3) <= 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 <= 4, 2 LIKE 1 ESCAPE (3 <= 4), (2 LIKE 1 ESCAPE 3) <= 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 < 4, 2 LIKE 1 ESCAPE (3 < 4), (2 LIKE 1 ESCAPE 3) < 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 < 4, 2 LIKE 1 ESCAPE (3 < 4), (2 LIKE 1 ESCAPE 3) < 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 <> 4, 2 LIKE 1 ESCAPE (3 <> 4), (2 LIKE 1 ESCAPE 3) <> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 <> 4, 2 LIKE 1 ESCAPE (3 <> 4), (2 LIKE 1 ESCAPE 3) <> 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 > 4, 2 LIKE 2 ESCAPE (3 > 4), (2 LIKE 2 ESCAPE 3) > 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 > 4, 2 LIKE 2 ESCAPE (3 > 4), (2 LIKE 2 ESCAPE 3) > 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 != 4, 2 LIKE 1 ESCAPE (3 != 4), (2 LIKE 1 ESCAPE 3) != 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 != 4, 2 LIKE 1 ESCAPE (3 != 4), (2 LIKE 1 ESCAPE 3) != 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 LIKE 4, 2 LIKE 2 ESCAPE (3 LIKE 4), (2 LIKE 2 ESCAPE 3) LIKE 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 LIKE 4, 2 LIKE 2 ESCAPE (3 LIKE 4), (2 LIKE 2 ESCAPE 3) LIKE 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 REGEXP 4, 2 LIKE 2 ESCAPE (3 REGEXP 4), (2 LIKE 2 ESCAPE 3) REGEXP 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 REGEXP 4, 2 LIKE 2 ESCAPE (3 REGEXP 4), (2 LIKE 2 ESCAPE 3) REGEXP 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 | 4, 2 LIKE 1 ESCAPE (3 | 4), (2 LIKE 1 ESCAPE 3) | 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 | 4, 2 LIKE 1 ESCAPE (3 | 4), (2 LIKE 1 ESCAPE 3) | 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 & 4, 2 LIKE 2 ESCAPE (3 & 4), (2 LIKE 2 ESCAPE 3) & 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 & 4, 2 LIKE 2 ESCAPE (3 & 4), (2 LIKE 2 ESCAPE 3) & 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 1 << 1, 2 LIKE 2 ESCAPE (1 << 1), (2 LIKE 2 ESCAPE 1) << 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 1 << 1, 2 LIKE 2 ESCAPE (1 << 1), (2 LIKE 2 ESCAPE 1) << 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 >> 4, 2 LIKE 2 ESCAPE (3 >> 4), (2 LIKE 2 ESCAPE 3) >> 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 >> 4, 2 LIKE 2 ESCAPE (3 >> 4), (2 LIKE 2 ESCAPE 3) >> 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY, 2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY), (2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 +INTERVAL 1 DAY, 2 LIKE 1 ESCAPE (3 +INTERVAL 1 DAY), (2 LIKE 1 ESCAPE 3) +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 + 4, 2 LIKE 1 ESCAPE (3 + 4), (2 LIKE 1 ESCAPE 3) + 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 + 4, 2 LIKE 1 ESCAPE (3 + 4), (2 LIKE 1 ESCAPE 3) + 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 1 - 1, 2 LIKE 2 ESCAPE (1 - 1), (2 LIKE 2 ESCAPE 1) - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 1 - 1, 2 LIKE 2 ESCAPE (1 - 1), (2 LIKE 2 ESCAPE 1) - 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 * 0, 2 LIKE 2 ESCAPE (3 * 0), (2 LIKE 2 ESCAPE 3) * 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 * 0, 2 LIKE 2 ESCAPE (3 * 0), (2 LIKE 2 ESCAPE 3) * 0 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 DIV 3, 2 LIKE 2 ESCAPE (3 DIV 3), (2 LIKE 2 ESCAPE 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 DIV 3, 2 LIKE 2 ESCAPE (3 DIV 3), (2 LIKE 2 ESCAPE 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 MOD 1, 2 LIKE 2 ESCAPE (3 MOD 1), (2 LIKE 2 ESCAPE 3) MOD 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 MOD 1, 2 LIKE 2 ESCAPE (3 MOD 1), (2 LIKE 2 ESCAPE 3) MOD 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 % 1, 2 LIKE 2 ESCAPE (3 % 1), (2 LIKE 2 ESCAPE 3) % 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 % 1, 2 LIKE 2 ESCAPE (3 % 1), (2 LIKE 2 ESCAPE 3) % 1 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 ^ 4, 2 LIKE 1 ESCAPE (3 ^ 4), (2 LIKE 1 ESCAPE 3) ^ 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 ^ 4, 2 LIKE 1 ESCAPE (3 ^ 4), (2 LIKE 1 ESCAPE 3) ^ 4 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4, 2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4), (2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 2 ESCAPE 3 BETWEEN 2 AND 4, 2 LIKE 2 ESCAPE (3 BETWEEN 2 AND 4), (2 LIKE 2 ESCAPE 3) BETWEEN 2 AND 4 union select * from v1;
+
+create or replace view v1 as select NOT 2 IN (SELECT 0 UNION SELECT 2), NOT (2 IN (SELECT 0 UNION SELECT 2)), (NOT 2) IN (SELECT 0 UNION SELECT 2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 IN (SELECT 0 UNION SELECT 2), NOT (2 IN (SELECT 0 UNION SELECT 2)), (NOT 2) IN (SELECT 0 UNION SELECT 2) union select * from v1;
+
+create or replace view v1 as select - 2 IN (SELECT 2 UNION SELECT 1), - (2 IN (SELECT 2 UNION SELECT 1)), (- 2) IN (SELECT 2 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - 2 IN (SELECT 2 UNION SELECT 1), - (2 IN (SELECT 2 UNION SELECT 1)), (- 2) IN (SELECT 2 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select ~ 2 IN (SELECT 0 UNION SELECT 1), ~ (2 IN (SELECT 0 UNION SELECT 1)), (~ 2) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 IN (SELECT 0 UNION SELECT 1), ~ (2 IN (SELECT 0 UNION SELECT 1)), (~ 2) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select ! 2 IN (SELECT 0 UNION SELECT 2), ! (2 IN (SELECT 0 UNION SELECT 2)), (! 2) IN (SELECT 0 UNION SELECT 2);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 IN (SELECT 0 UNION SELECT 2), ! (2 IN (SELECT 0 UNION SELECT 2)), (! 2) IN (SELECT 0 UNION SELECT 2) union select * from v1;
+
+create or replace view v1 as select BINARY 'c' IN (SELECT 'C' UNION SELECT 'X'), BINARY ('c' IN (SELECT 'C' UNION SELECT 'X')), (BINARY 'c') IN (SELECT 'C' UNION SELECT 'X');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select BINARY 'c' IN (SELECT 'C' UNION SELECT 'X'), BINARY ('c' IN (SELECT 'C' UNION SELECT 'X')), (BINARY 'c') IN (SELECT 'C' UNION SELECT 'X') union select * from v1;
+
+create or replace view v1 as select 0 OR 3 IN (SELECT 3 UNION SELECT 10), 0 OR (3 IN (SELECT 3 UNION SELECT 10)), (0 OR 3) IN (SELECT 3 UNION SELECT 10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 OR 3 IN (SELECT 3 UNION SELECT 10), 0 OR (3 IN (SELECT 3 UNION SELECT 10)), (0 OR 3) IN (SELECT 3 UNION SELECT 10) union select * from v1;
+
+create or replace view v1 as select 0 || 3 IN (SELECT 3 UNION SELECT 10), 0 || (3 IN (SELECT 3 UNION SELECT 10)), (0 || 3) IN (SELECT 3 UNION SELECT 10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 IN (SELECT 3 UNION SELECT 10), 0 || (3 IN (SELECT 3 UNION SELECT 10)), (0 || 3) IN (SELECT 3 UNION SELECT 10) union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 IN (SELECT 4 UNION SELECT 5), 2 XOR (3 IN (SELECT 4 UNION SELECT 5)), (2 XOR 3) IN (SELECT 4 UNION SELECT 5);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 IN (SELECT 4 UNION SELECT 5), 2 XOR (3 IN (SELECT 4 UNION SELECT 5)), (2 XOR 3) IN (SELECT 4 UNION SELECT 5) union select * from v1;
+
+create or replace view v1 as select 2 AND 3 IN (SELECT 0 UNION SELECT 1), 2 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 AND 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 AND 3 IN (SELECT 0 UNION SELECT 1), 2 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 AND 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 && 3 IN (SELECT 0 UNION SELECT 1), 2 && (3 IN (SELECT 0 UNION SELECT 1)), (2 && 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 && 3 IN (SELECT 0 UNION SELECT 1), 2 && (3 IN (SELECT 0 UNION SELECT 1)), (2 && 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 = 3 IN (SELECT 0 UNION SELECT 1), 2 = (3 IN (SELECT 0 UNION SELECT 1)), (2 = 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 IN (SELECT 0 UNION SELECT 1), 2 = (3 IN (SELECT 0 UNION SELECT 1)), (2 = 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 IN (SELECT 0 UNION SELECT 1), 2 <=> (3 IN (SELECT 0 UNION SELECT 1)), (2 <=> 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 IN (SELECT 0 UNION SELECT 1), 2 <=> (3 IN (SELECT 0 UNION SELECT 1)), (2 <=> 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 >= 3 IN (SELECT 1 UNION SELECT 1), 2 >= (3 IN (SELECT 1 UNION SELECT 1)), (2 >= 3) IN (SELECT 1 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 IN (SELECT 1 UNION SELECT 1), 2 >= (3 IN (SELECT 1 UNION SELECT 1)), (2 >= 3) IN (SELECT 1 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 <= 3 IN (SELECT 0 UNION SELECT 1), 2 <= (3 IN (SELECT 0 UNION SELECT 1)), (2 <= 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 IN (SELECT 0 UNION SELECT 1), 2 <= (3 IN (SELECT 0 UNION SELECT 1)), (2 <= 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 < 3 IN (SELECT 0 UNION SELECT 1), 2 < (3 IN (SELECT 0 UNION SELECT 1)), (2 < 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 IN (SELECT 0 UNION SELECT 1), 2 < (3 IN (SELECT 0 UNION SELECT 1)), (2 < 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 <> 3 IN (SELECT 0 UNION SELECT 0), 2 <> (3 IN (SELECT 0 UNION SELECT 0)), (2 <> 3) IN (SELECT 0 UNION SELECT 0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <> 3 IN (SELECT 0 UNION SELECT 0), 2 <> (3 IN (SELECT 0 UNION SELECT 0)), (2 <> 3) IN (SELECT 0 UNION SELECT 0) union select * from v1;
+
+create or replace view v1 as select 2 > 3 IN (SELECT 1 UNION SELECT 1), 2 > (3 IN (SELECT 1 UNION SELECT 1)), (2 > 3) IN (SELECT 1 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 > 3 IN (SELECT 1 UNION SELECT 1), 2 > (3 IN (SELECT 1 UNION SELECT 1)), (2 > 3) IN (SELECT 1 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 != 3 IN (SELECT 0 UNION SELECT 0), 2 != (3 IN (SELECT 0 UNION SELECT 0)), (2 != 3) IN (SELECT 0 UNION SELECT 0);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 != 3 IN (SELECT 0 UNION SELECT 0), 2 != (3 IN (SELECT 0 UNION SELECT 0)), (2 != 3) IN (SELECT 0 UNION SELECT 0) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 IN (SELECT 0 UNION SELECT 1), 2 REGEXP (3 IN (SELECT 0 UNION SELECT 1)), (2 REGEXP 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 IN (SELECT 0 UNION SELECT 1), 2 REGEXP (3 IN (SELECT 0 UNION SELECT 1)), (2 REGEXP 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 | 3 IN (SELECT 0 UNION SELECT 1), 2 | (3 IN (SELECT 0 UNION SELECT 1)), (2 | 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 IN (SELECT 0 UNION SELECT 1), 2 | (3 IN (SELECT 0 UNION SELECT 1)), (2 | 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 & 4 IN (SELECT 0 UNION SELECT 1), 2 & (4 IN (SELECT 0 UNION SELECT 1)), (2 & 4) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 4 IN (SELECT 0 UNION SELECT 1), 2 & (4 IN (SELECT 0 UNION SELECT 1)), (2 & 4) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 << 3 IN (SELECT 0 UNION SELECT 1), 2 << (3 IN (SELECT 0 UNION SELECT 1)), (2 << 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 IN (SELECT 0 UNION SELECT 1), 2 << (3 IN (SELECT 0 UNION SELECT 1)), (2 << 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 >> 3 IN (SELECT 0 UNION SELECT 1), 2 >> (3 IN (SELECT 0 UNION SELECT 1)), (2 >> 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 IN (SELECT 0 UNION SELECT 1), 2 >> (3 IN (SELECT 0 UNION SELECT 1)), (2 >> 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 + 3 IN (SELECT 0 UNION SELECT 1), 2 + (3 IN (SELECT 0 UNION SELECT 1)), (2 + 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 IN (SELECT 0 UNION SELECT 1), 2 + (3 IN (SELECT 0 UNION SELECT 1)), (2 + 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 - 3 IN (SELECT 0 UNION SELECT 1), 2 - (3 IN (SELECT 0 UNION SELECT 1)), (2 - 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 3 IN (SELECT 0 UNION SELECT 1), 2 - (3 IN (SELECT 0 UNION SELECT 1)), (2 - 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 * 0 IN (SELECT 0 UNION SELECT 1), 2 * (0 IN (SELECT 0 UNION SELECT 1)), (2 * 0) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 0 IN (SELECT 0 UNION SELECT 1), 2 * (0 IN (SELECT 0 UNION SELECT 1)), (2 * 0) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 / 3 IN (SELECT 0 UNION SELECT 1), 2 / (3 IN (SELECT 0 UNION SELECT 1)), (2 / 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 IN (SELECT 0 UNION SELECT 1), 2 / (3 IN (SELECT 0 UNION SELECT 1)), (2 / 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 IN (SELECT 0 UNION SELECT 1), 2 DIV (3 IN (SELECT 0 UNION SELECT 1)), (2 DIV 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 IN (SELECT 0 UNION SELECT 1), 2 DIV (3 IN (SELECT 0 UNION SELECT 1)), (2 DIV 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 IN (SELECT 0 UNION SELECT 1), 2 MOD (3 IN (SELECT 0 UNION SELECT 1)), (2 MOD 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 IN (SELECT 0 UNION SELECT 1), 2 MOD (3 IN (SELECT 0 UNION SELECT 1)), (2 MOD 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 % 3 IN (SELECT 0 UNION SELECT 1), 2 % (3 IN (SELECT 0 UNION SELECT 1)), (2 % 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 IN (SELECT 0 UNION SELECT 1), 2 % (3 IN (SELECT 0 UNION SELECT 1)), (2 % 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 IN (SELECT 0 UNION SELECT 1), 2 ^ (3 IN (SELECT 0 UNION SELECT 1)), (2 ^ 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 IN (SELECT 0 UNION SELECT 1), 2 ^ (3 IN (SELECT 0 UNION SELECT 1)), (2 ^ 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1), 2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 IN (SELECT 0 UNION SELECT 1), 2 BETWEEN 1 AND (3 IN (SELECT 0 UNION SELECT 1)), (2 BETWEEN 1 AND 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 1 ESCAPE 3 IN (SELECT 0 UNION SELECT 1), 2 LIKE 1 ESCAPE (3 IN (SELECT 0 UNION SELECT 1)), (2 LIKE 1 ESCAPE 3) IN (SELECT 0 UNION SELECT 1) union select * from v1;
+
+create or replace view v1 as select 3 BETWEEN 1 AND 2 AND NULL, 3 BETWEEN (1 AND 2) AND NULL, 3 BETWEEN 1 AND (2 AND NULL), (3 BETWEEN 1 AND 2) AND NULL;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 3 BETWEEN 1 AND 2 AND NULL, 3 BETWEEN (1 AND 2) AND NULL, 3 BETWEEN 1 AND (2 AND NULL), (3 BETWEEN 1 AND 2) AND NULL union select * from v1;
+
+set sql_mode=PIPES_AS_CONCAT;
+create or replace view v1 as select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 OR 3 || 3, 2 OR (3 || 3), (2 OR 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 OR 3, 2 || (3 OR 3), (2 || 3) OR 3 union select * from v1;
+
+create or replace view v1 as select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select NOT 2 || 3, NOT (2 || 3), (NOT 2) || 3 union select * from v1;
+
+create or replace view v1 as select - '2 ' || 3, - ('2 ' || 3), (- '2 ') || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select - '2 ' || 3, - ('2 ' || 3), (- '2 ') || 3 union select * from v1;
+
+create or replace view v1 as select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ~ 2 || 3, ~ (2 || 3), (~ 2) || 3 union select * from v1;
+
+create or replace view v1 as select ! 2 || 3, ! (2 || 3), (! 2) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select ! 2 || 3, ! (2 || 3), (! 2) || 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 IS FALSE, 2 || (3 IS FALSE), (2 || 3) IS FALSE union select * from v1;
+
+create or replace view v1 as select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 IN (3,10), 0 || (3 IN (3,10)), (0 || 3) IN (3,10) union select * from v1;
+
+create or replace view v1 as select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 0 XOR 1, 1 || (0 XOR 1), (1 || 0) XOR 1 union select * from v1;
+
+create or replace view v1 as select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 1 AND 0, 1 || (1 AND 0), (1 || 1) AND 0 union select * from v1;
+
+create or replace view v1 as select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 || 1 && 0, 1 || (1 && 0), (1 || 1) && 0 union select * from v1;
+
+create or replace view v1 as select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 = 3, 2 || (3 = 3), (2 || 3) = 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 <=> 3, 2 || (3 <=> 3), (2 || 3) <=> 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 >= 3, 2 || (3 >= 3), (2 || 3) >= 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 <= 0, 2 || (3 <= 0), (2 || 3) <= 0 union select * from v1;
+
+create or replace view v1 as select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 < 0, 2 || (3 < 0), (2 || 3) < 0 union select * from v1;
+
+create or replace view v1 as select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 <> 3, 0 || (3 <> 3), (0 || 3) <> 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 > 3, 2 || (3 > 3), (2 || 3) > 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 != 3, 0 || (3 != 3), (0 || 3) != 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 LIKE 3, 2 || (3 LIKE 3), (2 || 3) LIKE 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 REGEXP 3, 2 || (3 REGEXP 3), (2 || 3) REGEXP 3 union select * from v1;
+
+create or replace view v1 as select 2 || ' 3' | 3, 2 || (' 3' | 3), (2 || ' 3') | 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || ' 3' | 3, 2 || (' 3' | 3), (2 || ' 3') | 3 union select * from v1;
+
+create or replace view v1 as select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 2 & 2, 0 || (2 & 2), (0 || 2) & 2 union select * from v1;
+
+create or replace view v1 as select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 << 3, 2 || (3 << 3), (2 || 3) << 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 >> 3, 2 || (3 >> 3), (2 || 3) >> 3 union select * from v1;
+
+create or replace view v1 as select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || '2000-01-01' +INTERVAL 1 DAY, 2 || ('2000-01-01' +INTERVAL 1 DAY), (2 || '2000-01-01') +INTERVAL 1 DAY union select * from v1;
+
+create or replace view v1 as select 2 || ' 3' + 3, 2 || (' 3' + 3), (2 || ' 3') + 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || ' 3' + 3, 2 || (' 3' + 3), (2 || ' 3') + 3 union select * from v1;
+
+create or replace view v1 as select 2 || ' 3' - 3, 2 || (' 3' - 3), (2 || ' 3') - 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || ' 3' - 3, 2 || (' 3' - 3), (2 || ' 3') - 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 * 3, 2 || (3 * 3), (2 || 3) * 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 / 3, 2 || (3 / 3), (2 || 3) / 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 DIV 3, 2 || (3 DIV 3), (2 || 3) DIV 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 MOD 3, 0 || (3 MOD 3), (0 || 3) MOD 3 union select * from v1;
+
+create or replace view v1 as select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 || 3 % 3, 0 || (3 % 3), (0 || 3) % 3 union select * from v1;
+
+create or replace view v1 as select 2 || ' 3' ^ 3, 2 || (' 3' ^ 3), (2 || ' 3') ^ 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || ' 3' ^ 3, 2 || (' 3' ^ 3), (2 || ' 3') ^ 3 union select * from v1;
+
+create or replace view v1 as select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 || 3 BETWEEN 2 AND 3, 2 || (3 BETWEEN 2 AND 3), (2 || 3) BETWEEN 2 AND 3 union select * from v1;
+
+create or replace view v1 as select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 XOR 3 || 3, 2 XOR (3 || 3), (2 XOR 3) || 3 union select * from v1;
+
+create or replace view v1 as select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 AND 3 || 3, 0 AND (3 || 3), (0 AND 3) || 3 union select * from v1;
+
+create or replace view v1 as select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 && 3 || 3, 0 && (3 || 3), (0 && 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 = 3 || 3, 2 = (3 || 3), (2 = 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <=> 3 || 3, 2 <=> (3 || 3), (2 <=> 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >= 3 || 0, 2 >= (3 || 0), (2 >= 3) || 0 union select * from v1;
+
+create or replace view v1 as select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 <= 3 || 3, 2 <= (3 || 3), (2 <= 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 < 3 || 3, 2 < (3 || 3), (2 < 3) || 3 union select * from v1;
+
+create or replace view v1 as select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 <> 3 || 3, 1 <> (3 || 3), (1 <> 3) || 3 union select * from v1;
+
+create or replace view v1 as select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 0 > 3 || 3, 0 > (3 || 3), (0 > 3) || 3 union select * from v1;
+
+create or replace view v1 as select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 1 != 3 || 3, 1 != (3 || 3), (1 != 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 LIKE 3 || 3, 2 LIKE (3 || 3), (2 LIKE 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 REGEXP 3 || 3, 2 REGEXP (3 || 3), (2 REGEXP 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 | 3 || 3, 2 | (3 || 3), (2 | 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 & 3 || 3, 2 & (3 || 3), (2 & 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 << 3 || 3, 2 << (3 || 3), (2 << 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 >> 3 || 0, 2 >> (3 || 0), (2 >> 3) || 0 union select * from v1;
+
+create or replace view v1 as select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 + 3 || 3, 2 + (3 || 3), (2 + 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 - 2 || 0, 2 - (2 || 0), (2 - 2) || 0 union select * from v1;
+
+create or replace view v1 as select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 * 3 || 3, 2 * (3 || 3), (2 * 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 / 3 || 3, 2 / (3 || 3), (2 / 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 DIV 3 || 3, 2 DIV (3 || 3), (2 DIV 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 MOD 3 || 3, 2 MOD (3 || 3), (2 MOD 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 % 3 || 3, 2 % (3 || 3), (2 % 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 ^ 3 || 3, 2 ^ (3 || 3), (2 ^ 3) || 3 union select * from v1;
+
+create or replace view v1 as select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select 2 BETWEEN 1 AND 3 || 3, 2 BETWEEN 1 AND (3 || 3), (2 BETWEEN 1 AND 3) || 3 union select * from v1;
+
+create or replace view v1 as select charset(2 LIKE 1 ESCAPE 3 || ''), charset(2 LIKE 1 ESCAPE (3 || '')), charset((2 LIKE 1 ESCAPE 3) || '');
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+select charset(2 LIKE 1 ESCAPE 3 || ''), charset(2 LIKE 1 ESCAPE (3 || '')), charset((2 LIKE 1 ESCAPE 3) || '') union select * from v1;
+
+# not precedence tests as such, but still tests of Item::print, parentheses and enum precedence
+
+create or replace view v1 as select ! - 1, - ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select ! BINARY 1, BINARY ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select ! (NOT 1), NOT ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select ! ~ 1, ~ ! 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select - BINARY 1, BINARY - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select - (NOT 1), NOT - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select - ~ 1, ~ - 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select BINARY (NOT 1), NOT BINARY 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select BINARY ~ 1, ~ BINARY 1;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select NOT ~ 1, ~ (NOT 1);
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+create or replace view v1 as select 1 IS TRUE IS FALSE, 2 IS FALSE IS UNKNOWN, 3 IS UNKNOWN IS NULL, 4 IS NULL IS TRUE;
+Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
+
+drop view v1;
diff --git a/mysql-test/main/precedence_bugs.result b/mysql-test/main/precedence_bugs.result
new file mode 100644
index 00000000000..4b13e820d7f
--- /dev/null
+++ b/mysql-test/main/precedence_bugs.result
@@ -0,0 +1,60 @@
+#
+# Bug#6726: NOT BETWEEN parse failure
+#
+create table t1 (a int, b int);
+insert into t1 values (1,2), (2,3), (3,4), (4,5);
+select * from t1 where a not between 1 and 2;
+a b
+3 4
+4 5
+select * from t1 where a not between 1 and 2 and b not between 3 and 4;
+a b
+4 5
+drop table t1;
+#
+# MDEV-13673 Bad result in view
+#
+explain extended select (3-2)+1, (3/2)*1, 3-(2+1), 3/(2*1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 3 - 2 + 1 AS `(3-2)+1`,3 / 2 * 1 AS `(3/2)*1`,3 - (2 + 1) AS `3-(2+1)`,3 / (2 * 1) AS `3/(2*1)`
+#
+# MDEV-11784 View is created with invalid definition which causes ERROR 1241 (21000): Operand should contain 1 column(s)
+#
+create table t1 (i int, j int);
+insert t1 values (1,1),(2,2);
+create view v1 as select (2, 3) not in (select i, j from t1);
+select * from v1;
+(2, 3) not in (select i, j from t1)
+1
+show create view v1;
+View v1
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select !((2,3) in (select `t1`.`i`,`t1`.`j` from `t1`)) AS `(2, 3) not in (select i, j from t1)`
+character_set_client latin1
+collation_connection latin1_swedish_ci
+drop view v1;
+drop table t1;
+#
+# MDEV-23656 view: removal of parentheses results in wrong result
+#
+create table t1 (a int, b decimal(10,2));
+insert into t1 values (1, 10.2);
+create view v1 as select avg(b) / (2 + a) from t1;
+show create view v1;
+View v1
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select avg(`t1`.`b`) / (2 + `t1`.`a`) AS `avg(b) / (2 + a)` from `t1`
+character_set_client latin1
+collation_connection latin1_swedish_ci
+drop view v1;
+drop table t1;
+#
+# MDEV-17408 VIEW is incorrectly defined for a combination of = and BETWEEN
+#
+create view v1 as select 1 like (now() between '2000-01-01' and '2012-12-12' );
+show create view v1;
+View v1
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 like (current_timestamp() between '2000-01-01' and '2012-12-12') AS `1 like (now() between '2000-01-01' and '2012-12-12' )`
+character_set_client latin1
+collation_connection latin1_swedish_ci
+drop view v1;
diff --git a/mysql-test/main/precedence_bugs.test b/mysql-test/main/precedence_bugs.test
new file mode 100644
index 00000000000..6e8e624c840
--- /dev/null
+++ b/mysql-test/main/precedence_bugs.test
@@ -0,0 +1,41 @@
+--echo #
+--echo # Bug#6726: NOT BETWEEN parse failure
+--echo #
+create table t1 (a int, b int);
+insert into t1 values (1,2), (2,3), (3,4), (4,5);
+select * from t1 where a not between 1 and 2;
+select * from t1 where a not between 1 and 2 and b not between 3 and 4;
+drop table t1;
+
+--echo #
+--echo # MDEV-13673 Bad result in view
+--echo #
+explain extended select (3-2)+1, (3/2)*1, 3-(2+1), 3/(2*1);
+
+--echo #
+--echo # MDEV-11784 View is created with invalid definition which causes ERROR 1241 (21000): Operand should contain 1 column(s)
+--echo #
+create table t1 (i int, j int);
+insert t1 values (1,1),(2,2);
+create view v1 as select (2, 3) not in (select i, j from t1);
+select * from v1;
+query_vertical show create view v1;
+drop view v1;
+drop table t1;
+
+--echo #
+--echo # MDEV-23656 view: removal of parentheses results in wrong result
+--echo #
+create table t1 (a int, b decimal(10,2));
+insert into t1 values (1, 10.2);
+create view v1 as select avg(b) / (2 + a) from t1;
+query_vertical show create view v1;
+drop view v1;
+drop table t1;
+
+--echo #
+--echo # MDEV-17408 VIEW is incorrectly defined for a combination of = and BETWEEN
+--echo #
+create view v1 as select 1 like (now() between '2000-01-01' and '2012-12-12' );
+query_vertical show create view v1;
+drop view v1;
diff --git a/mysql-test/main/processlist_notembedded.result b/mysql-test/main/processlist_notembedded.result
index b622fdf32b9..3c2671ff5e3 100644
--- a/mysql-test/main/processlist_notembedded.result
+++ b/mysql-test/main/processlist_notembedded.result
@@ -14,3 +14,16 @@ disconnect con1;
connection default;
SET DEBUG_SYNC = 'RESET';
End of 5.5 tests
+#
+# MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep
+#
+connect con1,localhost,root,,;
+select sleep(100000);;
+connection default;
+SHOW EXPLAIN FOR con_id;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select sleep(100000)
+KILL QUERY con_id;
+# End of 10.2 tests
diff --git a/mysql-test/main/processlist_notembedded.test b/mysql-test/main/processlist_notembedded.test
index 6f269a816fc..26021040c39 100644
--- a/mysql-test/main/processlist_notembedded.test
+++ b/mysql-test/main/processlist_notembedded.test
@@ -40,3 +40,21 @@ SET DEBUG_SYNC = 'RESET';
source include/wait_until_count_sessions.inc;
--echo End of 5.5 tests
+
+--echo #
+--echo # MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep
+--echo #
+
+--connect (con1,localhost,root,,)
+--let $con_id = `SELECT CONNECTION_ID()`
+--send select sleep(100000);
+
+--connection default
+
+--replace_result $con_id con_id
+eval SHOW EXPLAIN FOR $con_id;
+
+--replace_result $con_id con_id
+eval KILL QUERY $con_id;
+
+--echo # End of 10.2 tests
diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result
index 837adf472f9..a9c3b9c6e2a 100644
--- a/mysql-test/main/range.result
+++ b/mysql-test/main/range.result
@@ -1297,7 +1297,7 @@ SELECT * FROM t1 WHERE
25 <= a AND b = 23 OR
23 <= a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
SELECT * FROM t1 WHERE
23 <= a AND a <= 25 OR
25 <= a AND b = 23 OR
@@ -3121,6 +3121,82 @@ a b
set eq_range_index_dive_limit=default;
drop table t1;
#
+# MDEV-23811: Both disjunct of WHERE condition contain range conditions
+# for the same index such that the second range condition
+# fully covers the first one. Additionally one of the disjuncts
+# contains a range condition for the other index.
+#
+create table t1 (
+pk int primary key auto_increment, a int, b int,
+index idx1(a), index idx2(b)
+);
+insert into t1(a,b) values
+(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
+insert into t1(a,b) select a+10, b+100 from t1;
+insert into t1(a,b) select a+20, b+200 from t1;
+insert into t1(a,b) select a+30, b+300 from t1;
+insert into t1(a,b) select a,b from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
+select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+pk a b
+7 2 20
+71 2 20
+3 3 30
+67 3 30
+6 4 40
+70 4 40
+1 5 50
+65 5 50
+explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
+select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+pk a b
+7 2 20
+71 2 20
+3 3 30
+67 3 30
+6 4 40
+70 4 40
+1 5 50
+65 5 50
+explain select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
+select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
+pk a b
+7 2 20
+71 2 20
+3 3 30
+67 3 30
+6 4 40
+70 4 40
+1 5 50
+65 5 50
+explain select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
+select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
+pk a b
+7 2 20
+71 2 20
+3 3 30
+67 3 30
+6 4 40
+70 4 40
+1 5 50
+65 5 50
+drop table t1;
+#
+# End of 10.2 tests
+#
+#
# MDEV-18551: New defaults for eq_range_index_dive_limit
#
create table ten(a int);
@@ -3140,9 +3216,7 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 range a a 5 NULL 201 1201.00 100.00 100.00 Using where; Using index
drop table t1,ten,t2;
-#
-# End of 10.2 tests
-#
+# End of 10.4 tests
#
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
#
diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test
index f19ed39e58c..8b25c0dffcc 100644
--- a/mysql-test/main/range.test
+++ b/mysql-test/main/range.test
@@ -2093,6 +2093,52 @@ set eq_range_index_dive_limit=default;
drop table t1;
--echo #
+--echo # MDEV-23811: Both disjunct of WHERE condition contain range conditions
+--echo # for the same index such that the second range condition
+--echo # fully covers the first one. Additionally one of the disjuncts
+--echo # contains a range condition for the other index.
+--echo #
+
+create table t1 (
+ pk int primary key auto_increment, a int, b int,
+ index idx1(a), index idx2(b)
+);
+insert into t1(a,b) values
+ (5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
+insert into t1(a,b) select a+10, b+100 from t1;
+insert into t1(a,b) select a+20, b+200 from t1;
+insert into t1(a,b) select a+30, b+300 from t1;
+insert into t1(a,b) select a,b from t1;
+
+analyze table t1;
+
+let $q1=
+select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+eval explain $q1;
+eval $q1;
+
+let $q2=
+select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+eval explain $q2;
+eval $q2;
+
+let $q3=
+select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
+eval explain $q3;
+eval $q3;
+
+let $q4=
+select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
+eval explain $q4;
+eval $q4;
+
+drop table t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
--echo # MDEV-18551: New defaults for eq_range_index_dive_limit
--echo #
@@ -2115,9 +2161,7 @@ let $a= `select group_concat(a) from t2`;
eval analyze SELECT * FROM t1 where a in ($a);
drop table t1,ten,t2;
---echo #
---echo # End of 10.2 tests
---echo #
+--echo # End of 10.4 tests
--echo #
--echo # MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result
index cfbb66b06ad..37a6f2de2fd 100644
--- a/mysql-test/main/range_mrr_icp.result
+++ b/mysql-test/main/range_mrr_icp.result
@@ -1300,7 +1300,7 @@ SELECT * FROM t1 WHERE
25 <= a AND b = 23 OR
23 <= a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
SELECT * FROM t1 WHERE
23 <= a AND a <= 25 OR
25 <= a AND b = 23 OR
@@ -3110,6 +3110,82 @@ a b
set eq_range_index_dive_limit=default;
drop table t1;
#
+# MDEV-23811: Both disjunct of WHERE condition contain range conditions
+# for the same index such that the second range condition
+# fully covers the first one. Additionally one of the disjuncts
+# contains a range condition for the other index.
+#
+create table t1 (
+pk int primary key auto_increment, a int, b int,
+index idx1(a), index idx2(b)
+);
+insert into t1(a,b) values
+(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
+insert into t1(a,b) select a+10, b+100 from t1;
+insert into t1(a,b) select a+20, b+200 from t1;
+insert into t1(a,b) select a+30, b+300 from t1;
+insert into t1(a,b) select a,b from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
+pk a b
+1 5 50
+3 3 30
+6 4 40
+7 2 20
+65 5 50
+67 3 30
+70 4 40
+71 2 20
+explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
+pk a b
+1 5 50
+3 3 30
+6 4 40
+7 2 20
+65 5 50
+67 3 30
+70 4 40
+71 2 20
+explain select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
+pk a b
+1 5 50
+3 3 30
+6 4 40
+7 2 20
+65 5 50
+67 3 30
+70 4 40
+71 2 20
+explain select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
+pk a b
+1 5 50
+3 3 30
+6 4 40
+7 2 20
+65 5 50
+67 3 30
+70 4 40
+71 2 20
+drop table t1;
+#
+# End of 10.2 tests
+#
+#
# MDEV-18551: New defaults for eq_range_index_dive_limit
#
create table ten(a int);
@@ -3129,9 +3205,7 @@ analyze SELECT * FROM t1 where a in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 range a a 5 NULL 201 1201.00 100.00 100.00 Using where; Using index
drop table t1,ten,t2;
-#
-# End of 10.2 tests
-#
+# End of 10.4 tests
#
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
#
diff --git a/mysql-test/main/range_vs_index_merge_innodb.result b/mysql-test/main/range_vs_index_merge_innodb.result
index f69425fee8b..497aa3d94dc 100644
--- a/mysql-test/main/range_vs_index_merge_innodb.result
+++ b/mysql-test/main/range_vs_index_merge_innodb.result
@@ -374,7 +374,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 200) AND
(Name LIKE 'Pa%' OR (Population > 103200 AND Population < 104000)));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Population,PRIMARY 39,4,4 NULL 302 Using sort_union(Name,Population,PRIMARY); Using where
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where
SELECT * FROM City USE INDEX ()
WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 110) AND
diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result
index 83cf932bdae..376cb63944a 100644
--- a/mysql-test/main/rowid_filter.result
+++ b/mysql-test/main/rowid_filter.result
@@ -1738,7 +1738,7 @@ EXPLAIN
"key_length": "9",
"used_key_parts": ["o_totaldiscount"],
"rows": 39,
- "filtered": 1.949866652,
+ "filtered": "REPLACED",
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
},
@@ -1756,7 +1756,7 @@ EXPLAIN
"used_key_parts": ["l_orderkey"],
"ref": ["dbt3_s001.orders.o_orderkey"],
"rows": 4,
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
}
@@ -1768,8 +1768,8 @@ o_totaldiscount BETWEEN 18000 AND 20000 AND
o_totalprice BETWEEN 200000 AND 220000 AND
l_shipdate BETWEEN '1996-10-01' AND '1996-12-01';
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
-1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 1.95 2.44 Using index condition; Using where
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where
+1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 # 2.44 Using index condition; Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where
set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate
FROM v1, lineitem
WHERE o_orderkey=l_orderkey AND
@@ -1799,7 +1799,7 @@ ANALYZE
"r_rows": 41,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 1.949866652,
+ "filtered": "REPLACED",
"r_filtered": 2.43902439,
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
@@ -1822,7 +1822,7 @@ ANALYZE
"r_rows": 6,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"r_filtered": 66.66666667,
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
@@ -1871,7 +1871,7 @@ EXPLAIN
"key_length": "9",
"used_key_parts": ["o_totaldiscount"],
"rows": 39,
- "filtered": 1.949866652,
+ "filtered": "REPLACED",
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
},
@@ -1889,7 +1889,7 @@ EXPLAIN
"used_key_parts": ["l_orderkey"],
"ref": ["dbt3_s001.orders.o_orderkey"],
"rows": 4,
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
}
@@ -1901,8 +1901,8 @@ o_totaldiscount BETWEEN 18000 AND 20000 AND
o_totalprice BETWEEN 200000 AND 220000 AND
l_shipdate BETWEEN '1996-10-01' AND '1996-12-01';
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
-1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 1.95 2.44 Using index condition; Using where
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where
+1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 39 41.00 # 2.44 Using index condition; Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where
set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate
FROM v1, lineitem
WHERE o_orderkey=l_orderkey AND
@@ -1932,7 +1932,7 @@ ANALYZE
"r_rows": 41,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 1.949866652,
+ "filtered": "REPLACED",
"r_filtered": 2.43902439,
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
@@ -1955,7 +1955,7 @@ ANALYZE
"r_rows": 6,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"r_filtered": 66.66666667,
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
diff --git a/mysql-test/main/rowid_filter.test b/mysql-test/main/rowid_filter.test
index ed1227d3770..163b71b6153 100644
--- a/mysql-test/main/rowid_filter.test
+++ b/mysql-test/main/rowid_filter.test
@@ -216,17 +216,21 @@ WHERE o_orderkey=l_orderkey AND
l_shipdate BETWEEN '1996-10-01' AND '1996-12-01';
eval $with_filter EXPLAIN $q7;
+--replace_regex /"filtered": [0-9e\.\-+]*,/"filtered": "REPLACED",/
eval $with_filter EXPLAIN FORMAT=JSON $q7;
+--replace_column 11 #
eval $with_filter ANALYZE $q7;
---source include/analyze-format.inc
+--replace_regex /("(r_(total|table|other)_time_ms|r_buffer_size|r_filling_time_ms|filtered)": )[^, \n]*/\1"REPLACED"/
eval $with_filter ANALYZE FORMAT=JSON $q7;
--sorted_result
eval $with_filter $q7;
eval $without_filter EXPLAIN $q7;
+--replace_regex /"filtered": [0-9e\.\-+]*,/"filtered": "REPLACED",/
eval $without_filter EXPLAIN FORMAT=JSON $q7;
+--replace_column 11 #
eval $without_filter ANALYZE $q7;
---source include/analyze-format.inc
+--replace_regex /("(r_(total|table|other)_time_ms|r_buffer_size|r_filling_time_ms|filtered)": )[^, \n]*/\1"REPLACED"/
eval $without_filter ANALYZE FORMAT=JSON $q7;
--sorted_result
eval $without_filter $q7;
diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result
index b2d598ca229..ae52f9416b9 100644
--- a/mysql-test/main/rowid_filter_innodb.result
+++ b/mysql-test/main/rowid_filter_innodb.result
@@ -1687,7 +1687,7 @@ EXPLAIN
"key_length": "9",
"used_key_parts": ["o_totaldiscount"],
"rows": 41,
- "filtered": 2.071111202,
+ "filtered": "REPLACED",
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
},
@@ -1705,7 +1705,7 @@ EXPLAIN
"used_key_parts": ["l_orderkey"],
"ref": ["dbt3_s001.orders.o_orderkey"],
"rows": 4,
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
}
@@ -1717,8 +1717,8 @@ o_totaldiscount BETWEEN 18000 AND 20000 AND
o_totalprice BETWEEN 200000 AND 220000 AND
l_shipdate BETWEEN '1996-10-01' AND '1996-12-01';
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
-1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 41 41.00 2.07 2.44 Using index condition; Using where
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where
+1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 41 41.00 # 2.44 Using index condition; Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where
set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate
FROM v1, lineitem
WHERE o_orderkey=l_orderkey AND
@@ -1748,7 +1748,7 @@ ANALYZE
"r_rows": 41,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 2.071111202,
+ "filtered": "REPLACED",
"r_filtered": 2.43902439,
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
@@ -1771,7 +1771,7 @@ ANALYZE
"r_rows": 6,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"r_filtered": 66.66666667,
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
@@ -1820,7 +1820,7 @@ EXPLAIN
"key_length": "9",
"used_key_parts": ["o_totaldiscount"],
"rows": 41,
- "filtered": 2.071111202,
+ "filtered": "REPLACED",
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
},
@@ -1838,7 +1838,7 @@ EXPLAIN
"used_key_parts": ["l_orderkey"],
"ref": ["dbt3_s001.orders.o_orderkey"],
"rows": 4,
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
}
@@ -1850,8 +1850,8 @@ o_totaldiscount BETWEEN 18000 AND 20000 AND
o_totalprice BETWEEN 200000 AND 220000 AND
l_shipdate BETWEEN '1996-10-01' AND '1996-12-01';
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
-1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 41 41.00 2.07 2.44 Using index condition; Using where
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 3.05 66.67 Using where
+1 SIMPLE orders range PRIMARY,i_o_orderdate,i_o_totalprice,i_o_totaldiscount i_o_totaldiscount 9 NULL 41 41.00 # 2.44 Using index condition; Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 6.00 # 66.67 Using where
set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT o_totaldiscount, o_totalprice, l_shipdate
FROM v1, lineitem
WHERE o_orderkey=l_orderkey AND
@@ -1881,7 +1881,7 @@ ANALYZE
"r_rows": 41,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 2.071111202,
+ "filtered": "REPLACED",
"r_filtered": 2.43902439,
"index_condition": "orders.o_totaldiscount between 18000 and 20000",
"attached_condition": "orders.o_totalprice between 200000 and 220000 and orders.o_orderDATE between '1992-12-01' and '1997-01-01'"
@@ -1904,7 +1904,7 @@ ANALYZE
"r_rows": 6,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 3.047460556,
+ "filtered": "REPLACED",
"r_filtered": 66.66666667,
"attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'"
}
diff --git a/mysql-test/main/rowid_filter_innodb_debug.result b/mysql-test/main/rowid_filter_innodb_debug.result
new file mode 100644
index 00000000000..6fd75294bdb
--- /dev/null
+++ b/mysql-test/main/rowid_filter_innodb_debug.result
@@ -0,0 +1,83 @@
+set default_storage_engine=innodb;
+#
+# MDEV-22761 KILL QUERY during rowid_filter, crashes
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2(a int);
+insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+CREATE TABLE t3 (
+key1 int ,
+key2 int,
+filler varchar(255),
+KEY (key1),
+KEY (key2)
+);
+select engine from information_schema.tables
+where table_schema=database() and table_name='t3';
+engine
+InnoDB
+insert into t3
+select
+A.a,
+A.a,
+'filler-data-filler-data'
+from
+t0 A, t1 B;
+analyze table t2,t3;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+test.t3 analyze status Engine-independent statistics collected
+test.t3 analyze status OK
+explain
+select * from t2, t3
+where
+t3.key1=t2.a and t3.key2 in (2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where
+1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1000 (20%) Using where; Using rowid filter
+set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go';
+select * from t2, t3
+where
+t3.key1=t2.a and t3.key2 in (2,3);
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR at_rowid_filter_check';
+kill query $target_id;
+set debug_sync='now SIGNAL go';
+connection default;
+disconnect con1;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+drop table t0,t1,t2,t3;
+set default_storage_engine=default;
+set @save_optimizer_switch= @@optimizer_switch;
+set @save_use_stat_tables= @@use_stat_tables;
+set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+set @@use_stat_tables=preferably;
+set optimizer_use_condition_selectivity=2;
+set optimizer_switch='rowid_filter=on';
+#
+# MDEV-22761 KILL QUERY during rowid_filter, crashes
+# (The smaller testcase)
+#
+CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
+set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go';
+SELECT * FROM t1 WHERE a > 0 AND b=0;
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR killme';
+kill query @id;
+set debug_sync='now SIGNAL go';
+connection default;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+disconnect con1;
+drop table t1;
+set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/main/rowid_filter_innodb_debug.test b/mysql-test/main/rowid_filter_innodb_debug.test
new file mode 100644
index 00000000000..eb43edd9e9e
--- /dev/null
+++ b/mysql-test/main/rowid_filter_innodb_debug.test
@@ -0,0 +1,51 @@
+--source include/have_innodb.inc
+
+set default_storage_engine=innodb;
+--source include/rowid_filter_debug_kill.inc
+set default_storage_engine=default;
+
+--source include/default_optimizer_switch.inc
+--source include/count_sessions.inc
+
+set @save_optimizer_switch= @@optimizer_switch;
+set @save_use_stat_tables= @@use_stat_tables;
+set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+
+set @@use_stat_tables=preferably;
+
+set optimizer_use_condition_selectivity=2;
+set optimizer_switch='rowid_filter=on';
+
+--echo #
+--echo # MDEV-22761 KILL QUERY during rowid_filter, crashes
+--echo # (The smaller testcase)
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
+
+let $ID= `SELECT @id := CONNECTION_ID()`;
+
+set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go';
+send SELECT * FROM t1 WHERE a > 0 AND b=0;
+
+connect (con1, localhost, root,,);
+connection con1;
+let $ignore= `SELECT @id := $ID`;
+set debug_sync='now WAIT_FOR killme';
+kill query @id;
+set debug_sync='now SIGNAL go';
+
+connection default;
+--error ER_QUERY_INTERRUPTED
+reap;
+set debug_sync='RESET';
+
+disconnect con1;
+drop table t1;
+
+set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@use_stat_tables=@save_use_stat_tables;
+
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/main/rowid_filter_myisam_debug.result b/mysql-test/main/rowid_filter_myisam_debug.result
new file mode 100644
index 00000000000..16fcb2a416e
--- /dev/null
+++ b/mysql-test/main/rowid_filter_myisam_debug.result
@@ -0,0 +1,54 @@
+#
+# MDEV-22761 KILL QUERY during rowid_filter, crashes
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2(a int);
+insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+CREATE TABLE t3 (
+key1 int ,
+key2 int,
+filler varchar(255),
+KEY (key1),
+KEY (key2)
+);
+select engine from information_schema.tables
+where table_schema=database() and table_name='t3';
+engine
+MyISAM
+insert into t3
+select
+A.a,
+A.a,
+'filler-data-filler-data'
+from
+t0 A, t1 B;
+analyze table t2,t3;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+test.t3 analyze status Engine-independent statistics collected
+test.t3 analyze status Table is already up to date
+explain
+select * from t2, t3
+where
+t3.key1=t2.a and t3.key2 in (2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where
+1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1000 (18%) Using where; Using rowid filter
+set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go';
+select * from t2, t3
+where
+t3.key1=t2.a and t3.key2 in (2,3);
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR at_rowid_filter_check';
+kill query $target_id;
+set debug_sync='now SIGNAL go';
+connection default;
+disconnect con1;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+drop table t0,t1,t2,t3;
diff --git a/mysql-test/main/rowid_filter_myisam_debug.test b/mysql-test/main/rowid_filter_myisam_debug.test
new file mode 100644
index 00000000000..ba2f79772a9
--- /dev/null
+++ b/mysql-test/main/rowid_filter_myisam_debug.test
@@ -0,0 +1,3 @@
+
+--source include/rowid_filter_debug_kill.inc
+
diff --git a/mysql-test/main/set_statement_notembedded.result b/mysql-test/main/set_statement_notembedded.result
index 17cf2f63da9..67d2d8bc505 100644
--- a/mysql-test/main/set_statement_notembedded.result
+++ b/mysql-test/main/set_statement_notembedded.result
@@ -7,9 +7,8 @@ SLEEP(1)
SHOW STATUS LIKE "max_statement_time_exceeded";
Variable_name Value
Max_statement_time_exceeded 0
-SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(3);
-SLEEP(3)
-1
+SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(10);
+ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
SHOW STATUS LIKE "max_statement_time_exceeded";
Variable_name Value
Max_statement_time_exceeded 1
diff --git a/mysql-test/main/set_statement_notembedded.test b/mysql-test/main/set_statement_notembedded.test
index 16488846fba..95d3efd40ca 100644
--- a/mysql-test/main/set_statement_notembedded.test
+++ b/mysql-test/main/set_statement_notembedded.test
@@ -6,7 +6,8 @@
SELECT @@MAX_STATEMENT_TIME;
SET STATEMENT MAX_STATEMENT_TIME=3 FOR SELECT SLEEP(1);
SHOW STATUS LIKE "max_statement_time_exceeded";
-SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(3);
+--error ER_STATEMENT_TIMEOUT
+SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(10);
SHOW STATUS LIKE "max_statement_time_exceeded";
SELECT @@MAX_STATEMENT_TIME;
diff --git a/mysql-test/main/sp-destruct.result b/mysql-test/main/sp-destruct.result
index 10cfcafdb3b..b5e01f8beeb 100644
--- a/mysql-test/main/sp-destruct.result
+++ b/mysql-test/main/sp-destruct.result
@@ -71,19 +71,49 @@ values
'alksj wpsj sa ^#!@ '
);
select bug14233_1();
-ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_1 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_1` is invalid
+Error 1064 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 'select count(*) from mysql.user' at line 3
+Error 1457 Failed to load routine test.bug14233_1 (internal code -6). For more details, run SHOW WARNINGS
create view v1 as select bug14233_1();
-ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_1 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_1` is invalid
+Error 1064 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 'select count(*) from mysql.user' at line 3
+Error 1457 Failed to load routine test.bug14233_1 (internal code -6). For more details, run SHOW WARNINGS
select bug14233_2();
-ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_2` is invalid
+Error 1320 No RETURN found in FUNCTION test.bug14233_2
+Error 1457 Failed to load routine test.bug14233_2 (internal code -6). For more details, run SHOW WARNINGS
create view v1 as select bug14233_2();
-ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_2` is invalid
+Error 1320 No RETURN found in FUNCTION test.bug14233_2
+Error 1457 Failed to load routine test.bug14233_2 (internal code -6). For more details, run SHOW WARNINGS
call bug14233_3();
-ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_3 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_3` is invalid
+Error 1064 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 'wpsj sa ^#!@ ' at line 3
+Error 1457 Failed to load routine test.bug14233_3 (internal code -6). For more details, run SHOW WARNINGS
drop trigger t1_ai;
create trigger t1_ai after insert on t1 for each row call bug14233_3();
insert into t1 values (0);
-ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.bug14233_3 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Warning 1601 Creation context of stored routine `test`.`bug14233_3` is invalid
+Error 1064 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 'wpsj sa ^#!@ ' at line 3
+Error 1457 Failed to load routine test.bug14233_3 (internal code -6). For more details, run SHOW WARNINGS
drop trigger t1_ai;
drop table t1;
drop function bug14233_1;
diff --git a/mysql-test/main/sp-destruct.test b/mysql-test/main/sp-destruct.test
index 12299fa230b..4bdfed70545 100644
--- a/mysql-test/main/sp-destruct.test
+++ b/mysql-test/main/sp-destruct.test
@@ -128,20 +128,26 @@ values
--error ER_SP_PROC_TABLE_CORRUPT
select bug14233_1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
create view v1 as select bug14233_1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
select bug14233_2();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
create view v1 as select bug14233_2();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
call bug14233_3();
+show warnings;
drop trigger t1_ai;
create trigger t1_ai after insert on t1 for each row call bug14233_3();
--error ER_SP_PROC_TABLE_CORRUPT
insert into t1 values (0);
+show warnings;
# Clean-up
drop trigger t1_ai;
diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result
index ed20689ed11..d5e722ff1bd 100644
--- a/mysql-test/main/sp.result
+++ b/mysql-test/main/sp.result
@@ -5304,8 +5304,12 @@ drop database if exists това_е_дълго_име_за_база_данни_Ð
create database това_е_дълго_име_за_база_данни_нали|
INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','', 'utf8', 'utf8_general_ci', 'utf8_general_ci', 'n/a', 'NONE')|
call това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго()|
-ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго (internal code -6). For more details, run SHOW WARNINGS
drop database това_е_дълго_име_за_база_данни_нали|
+show warnings|
+Level Code Message
+Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 2
+Error 1457 Failed to load routine това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго (internal code -6). For more details, run SHOW WARNINGS
CREATE TABLE t3 (
Member_ID varchar(15) NOT NULL,
PRIMARY KEY (Member_ID)
diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test
index bddd07bdb6c..c6c00ca8d91 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/sp.test
@@ -6315,7 +6315,7 @@ INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_да
--error ER_SP_PROC_TABLE_CORRUPT
call това_е_дълго_име_за_база_данни_нали.това_е_процедура_Ñ_доÑта_дълго_име_нали_и_още_по_дълго()|
drop database това_е_дълго_име_за_база_данни_нали|
-
+show warnings|
#
# BUG#21493: Crash on the second call of a procedure containing
diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result
index e937d1ffe0f..1f848f8c8eb 100644
--- a/mysql-test/main/stat_tables_innodb.result
+++ b/mysql-test/main/stat_tables_innodb.result
@@ -82,7 +82,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 Using index
1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index
1 SIMPLE orders ref|filter PRIMARY,i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (14%) Using where; Using rowid filter
-1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey 9 dbt3_s001.supplier.s_suppkey,dbt3_s001.orders.o_orderkey 1
select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue
from customer, orders, lineitem, supplier, nation, region
where c_custkey = o_custkey and l_orderkey = o_orderkey
@@ -213,7 +213,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 Using index
1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index
1 SIMPLE orders ref|filter PRIMARY,i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (14%) Using where; Using rowid filter
-1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 dbt3_s001.orders.o_orderkey 4 Using where
+1 SIMPLE lineitem ref PRIMARY,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity i_l_suppkey 9 dbt3_s001.supplier.s_suppkey,dbt3_s001.orders.o_orderkey 1
select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue
from customer, orders, lineitem, supplier, nation, region
where c_custkey = o_custkey and l_orderkey = o_orderkey
diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result
index 3f12322f6dc..00f61e9433b 100644
--- a/mysql-test/main/subselect4.result
+++ b/mysql-test/main/subselect4.result
@@ -2596,7 +2596,7 @@ 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
+11797 91 129.6374 129.637362637
SELECT * FROM t1 A
WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
region area population
diff --git a/mysql-test/main/sum_distinct-big.result b/mysql-test/main/sum_distinct-big.result
index 0556fd9a7c3..086dd33fad2 100644
--- a/mysql-test/main/sum_distinct-big.result
+++ b/mysql-test/main/sum_distinct-big.result
@@ -3,27 +3,7 @@ set @save_max_heap_table_size=@@max_heap_table_size;
set default_storage_engine=MYISAM;
CREATE TABLE t1 (id INTEGER);
CREATE TABLE t2 (id INTEGER);
-INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
-INSERT INTO t1 (id) SELECT id FROM t1;
-/* 8 */
-INSERT INTO t1 (id) SELECT id FROM t1;
-/* 12 */
-INSERT INTO t1 (id) SELECT id FROM t1;
-/* 16 */
-INSERT INTO t1 (id) SELECT id FROM t1;
-/* 20 */
-INSERT INTO t1 (id) SELECT id FROM t1;
-/* 24 */
-INSERT INTO t1 SELECT id+1 FROM t1;
-INSERT INTO t1 SELECT id+2 FROM t1;
-INSERT INTO t1 SELECT id+4 FROM t1;
-INSERT INTO t1 SELECT id+8 FROM t1;
-INSERT INTO t1 SELECT id+16 FROM t1;
-INSERT INTO t1 SELECT id+32 FROM t1;
-INSERT INTO t1 SELECT id+64 FROM t1;
-INSERT INTO t1 SELECT id+128 FROM t1;
-INSERT INTO t1 SELECT id+256 FROM t1;
-INSERT INTO t1 SELECT id+512 FROM t1;
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_1_to_1024 b;
SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13;
AVG(DISTINCT id)
513.5000
@@ -54,11 +34,9 @@ SUM(DISTINCT id)/COUNT(DISTINCT id)
517.0000
511.5000
512.5000
-INSERT INTO t1 SELECT id+1024 FROM t1;
-INSERT INTO t1 SELECT id+2048 FROM t1;
-INSERT INTO t1 SELECT id+4096 FROM t1;
-INSERT INTO t1 SELECT id+8192 FROM t1;
-INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_1025_to_16384 b;
+INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a,seq_1_to_16384 b
+ORDER by (a.seq*0+b.seq)*rand();
SELECT SUM(DISTINCT id) sm FROM t1;
sm
134225920
@@ -110,9 +88,10 @@ sm
# (bug #56927)
#
SET max_heap_table_size=default;
-INSERT INTO t1 SELECT id+16384 FROM t1;
-DELETE FROM t2;
-INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_16385_to_32768 b;
+TRUNCATE t2;
+INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a,seq_1_to_32768 b
+ORDER BY (a.seq*0+b.seq)*rand();
SELECT SUM(DISTINCT id) sm FROM t2;
sm
536887296
diff --git a/mysql-test/main/sum_distinct-big.test b/mysql-test/main/sum_distinct-big.test
index 42eeae743b1..41aa5a44c19 100644
--- a/mysql-test/main/sum_distinct-big.test
+++ b/mysql-test/main/sum_distinct-big.test
@@ -21,32 +21,15 @@ set default_storage_engine=MYISAM;
CREATE TABLE t1 (id INTEGER);
CREATE TABLE t2 (id INTEGER);
-INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
-INSERT INTO t1 (id) SELECT id FROM t1; /* 8 */
-INSERT INTO t1 (id) SELECT id FROM t1; /* 12 */
-INSERT INTO t1 (id) SELECT id FROM t1; /* 16 */
-INSERT INTO t1 (id) SELECT id FROM t1; /* 20 */
-INSERT INTO t1 (id) SELECT id FROM t1; /* 24 */
-INSERT INTO t1 SELECT id+1 FROM t1;
-INSERT INTO t1 SELECT id+2 FROM t1;
-INSERT INTO t1 SELECT id+4 FROM t1;
-INSERT INTO t1 SELECT id+8 FROM t1;
-INSERT INTO t1 SELECT id+16 FROM t1;
-INSERT INTO t1 SELECT id+32 FROM t1;
-INSERT INTO t1 SELECT id+64 FROM t1;
-INSERT INTO t1 SELECT id+128 FROM t1;
-INSERT INTO t1 SELECT id+256 FROM t1;
-INSERT INTO t1 SELECT id+512 FROM t1;
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_1_to_1024 b;
# Just test that AVG(DISTINCT) is there
SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13;
SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13;
-INSERT INTO t1 SELECT id+1024 FROM t1;
-INSERT INTO t1 SELECT id+2048 FROM t1;
-INSERT INTO t1 SELECT id+4096 FROM t1;
-INSERT INTO t1 SELECT id+8192 FROM t1;
-INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_1025_to_16384 b;
+INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a,seq_1_to_16384 b
+ORDER by (a.seq*0+b.seq)*rand();
# SELECT '++++++++++++++++++++++++++++++++++++++++++++++++++';
@@ -76,9 +59,10 @@ SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13;
SET max_heap_table_size=default;
-INSERT INTO t1 SELECT id+16384 FROM t1;
-DELETE FROM t2;
-INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
+INSERT INTO t1 SELECT b.seq FROM seq_1_to_128,seq_16385_to_32768 b;
+TRUNCATE t2;
+INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a,seq_1_to_32768 b
+ORDER BY (a.seq*0+b.seq)*rand();
SELECT SUM(DISTINCT id) sm FROM t2;
diff --git a/mysql-test/main/temp_table_symlink.test b/mysql-test/main/temp_table_symlink.test
index 35f956e8890..ea5f1dfa4de 100644
--- a/mysql-test/main/temp_table_symlink.test
+++ b/mysql-test/main/temp_table_symlink.test
@@ -12,9 +12,9 @@ chdir "$ENV{MYSQL_TMP_DIR}/mysqld.1/";
for (<#sql*.MYI>) {
/^(#sql-temptable-[0-9a-f]+)(-[0-9a-f]+-)([0-9a-f]+)\.MYI$/ or die $_;
symlink "$ENV{datadir}/test/d1.MYI", sprintf "$1$2%x.MYI", hex($3)+1;
- symlink "$ENV{datadir}/test/d1.MYI", sprintf "$1$2%x.MAI", hex($3)+1;
symlink "$ENV{datadir}/test/d1.MYI", sprintf "$1$2%x.MAI", hex($3)+2;
symlink "$ENV{datadir}/test/d1.MYI", sprintf "$1$2%x.MAI", hex($3)+3;
+ symlink "$ENV{datadir}/test/d1.MYI", sprintf "$1$2%x.MAI", hex($3)+4;
symlink "$ENV{datadir}/test/d1.MYI", "$1-0.MAI";
}
EOF
diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result
index f514f2169dd..28f5d8fb868 100644
--- a/mysql-test/main/type_blob.result
+++ b/mysql-test/main/type_blob.result
@@ -1125,5 +1125,20 @@ LENGTH(a) LENGTH(DEFAULT(a))
256 256
DROP TABLE t1;
#
+# ASAN heap-use-after-free in my_hash_sort_bin or ER_KEY_NOT_FOUND
+# upon INSERT into table with long unique blob
+#
+SET @save_sql_mode=@@sql_mode;
+SET SQL_MODE='STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT, b BLOB) ENGINE=innodb;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+CREATE TABLE t2 (c BIT, d BLOB, UNIQUE(d)) ENGINE=innodb;
+INSERT INTO t2 SELECT * FROM t1;
+ERROR 22001: Data too long for column 'c' at row 2
+select * from t2;
+c d
+DROP TABLE t1, t2;
+SET @@sql_mode=@save_sql_mode;
+#
# End of 10.4 test
#
diff --git a/mysql-test/main/type_blob.test b/mysql-test/main/type_blob.test
index dc483f036cd..38c8b9a83ca 100644
--- a/mysql-test/main/type_blob.test
+++ b/mysql-test/main/type_blob.test
@@ -1,6 +1,7 @@
# This test can't be run with running server (--extern) as this uses
# load_file() on a file in the tree.
#
+--source include/have_innodb.inc
#
# Basic cleanup
@@ -735,6 +736,25 @@ INSERT INTO t1 VALUES ();
SELECT LENGTH(a), LENGTH(DEFAULT(a)) FROM t1;
DROP TABLE t1;
+--echo #
+--echo # ASAN heap-use-after-free in my_hash_sort_bin or ER_KEY_NOT_FOUND
+--echo # upon INSERT into table with long unique blob
+--echo #
+
+# Note that this test worked with myisam as it caches blobs differently than
+# InnoDB
+
+SET @save_sql_mode=@@sql_mode;
+SET SQL_MODE='STRICT_ALL_TABLES';
+
+CREATE TABLE t1 (a INT, b BLOB) ENGINE=innodb;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+CREATE TABLE t2 (c BIT, d BLOB, UNIQUE(d)) ENGINE=innodb;
+--error ER_DATA_TOO_LONG
+INSERT INTO t2 SELECT * FROM t1;
+select * from t2;
+DROP TABLE t1, t2;
+SET @@sql_mode=@save_sql_mode;
--echo #
--echo # End of 10.4 test
diff --git a/mysql-test/main/type_newdecimal.result b/mysql-test/main/type_newdecimal.result
index eac263296e2..13974c84e15 100644
--- a/mysql-test/main/type_newdecimal.result
+++ b/mysql-test/main/type_newdecimal.result
@@ -1532,8 +1532,11 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000)
0.81298807395367312459230693948000000000
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` (
@@ -1648,6 +1651,8 @@ my_col
0.12345678912345678912345678912345678912
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/mysql-test/main/type_ranges.result b/mysql-test/main/type_ranges.result
index 199c8a45c97..784a394d8b5 100644
--- a/mysql-test/main/type_ranges.result
+++ b/mysql-test/main/type_ranges.result
@@ -91,6 +91,8 @@ 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 ignore 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 ignore 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
@@ -128,7 +130,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.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
+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
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
@@ -180,7 +182,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.3333 ne
+2 0.33333333 ne
3 -1 -1 ne
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
diff --git a/mysql-test/main/udf.result b/mysql-test/main/udf.result
index 8ad21e68c71..a6fabf7f137 100644
--- a/mysql-test/main/udf.result
+++ b/mysql-test/main/udf.result
@@ -479,9 +479,23 @@ myfunc_int(max(a) over (order by b) , b)
drop view v1;
drop function myfunc_int;
drop table t1;
-
-MDEV-15073: Generic UDAF parser code in server for windows functions
-
+#
+# MDEV-23327: Can't uninstall UDF if the implementation library
+# file doesn't exist
+#
+insert into mysql.func values ("unexisting_udf", 0, "soname", "function");
+select * from mysql.func WHERE name='unexisting_udf';
+name ret dl type
+unexisting_udf 0 soname function
+DROP FUNCTION unexisting_udf;
+select * from mysql.plugin WHERE name='unexisting_udf';
+name dl
+DROP FUNCTION unexisting_udf;
+ERROR 42000: FUNCTION test.unexisting_udf does not exist
+# End of 10.2 tests
+#
+# MDEV-15073: Generic UDAF parser code in server for window functions
+#
CREATE AGGREGATE FUNCTION avgcost
RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
CREATE AGGREGATE FUNCTION avg2
@@ -584,3 +598,4 @@ drop table t1;
DROP FUNCTION avgcost;
DROP FUNCTION avg2;
DROP FUNCTION myfunc_double;
+# End of 10.4 tests
diff --git a/mysql-test/main/udf.test b/mysql-test/main/udf.test
index 640d5567574..2e2272b2157 100644
--- a/mysql-test/main/udf.test
+++ b/mysql-test/main/udf.test
@@ -542,9 +542,31 @@ drop view v1;
drop function myfunc_int;
drop table t1;
---echo
---echo MDEV-15073: Generic UDAF parser code in server for windows functions
---echo
+--echo #
+--echo # MDEV-23327: Can't uninstall UDF if the implementation library
+--echo # file doesn't exist
+--echo #
+
+# emulate brocken so/ddl udf
+insert into mysql.func values ("unexisting_udf", 0, "soname", "function");
+
+# check that we have the function "installed"
+select * from mysql.func WHERE name='unexisting_udf';
+
+# make attempt to drop the function
+DROP FUNCTION unexisting_udf;
+
+# check that we have the plugin uninstalled
+select * from mysql.plugin WHERE name='unexisting_udf';
+
+--error ER_SP_DOES_NOT_EXIST
+DROP FUNCTION unexisting_udf;
+
+--echo # End of 10.2 tests
+
+--echo #
+--echo # MDEV-15073: Generic UDAF parser code in server for window functions
+--echo #
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
eval CREATE AGGREGATE FUNCTION avgcost
@@ -607,3 +629,5 @@ drop table t1;
DROP FUNCTION avgcost;
DROP FUNCTION avg2;
DROP FUNCTION myfunc_double;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result
index c1ed5d72d68..1891e3c44f7 100644
--- a/mysql-test/main/view.result
+++ b/mysql-test/main/view.result
@@ -6608,17 +6608,6 @@ INSERT INTO v (f1, f3) VALUES (1,1), (2,2);
ERROR HY000: Can not modify more than one base table through a join view 'test.v'
drop view v;
drop tables t1,t2,t3;
-create table t1 (i int, j int);
-insert t1 values (1,1),(2,2);
-create view v1 as select (2, 3) not in (select i, j from t1);
-select * from v1;
-(2, 3) not in (select i, j from t1)
-1
-show create view v1;
-View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select !((2,3) in (select `t1`.`i`,`t1`.`j` from `t1`)) AS `(2, 3) not in (select i, j from t1)` latin1 latin1_swedish_ci
-drop view v1;
-drop table t1;
#
# MDEV-10704: Assertion `field->field->table == table_arg'
# failed in fill_record(THD*, TABLE*, List<Item>&, List<Item>&,
diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test
index 0545810fa69..9b2baa69e8c 100644
--- a/mysql-test/main/view.test
+++ b/mysql-test/main/view.test
@@ -6303,17 +6303,6 @@ INSERT INTO v (f1, f3) VALUES (1,1), (2,2);
drop view v;
drop tables t1,t2,t3;
-#
-# MDEV-11784 View is created with invalid definition which causes ERROR 1241 (21000): Operand should contain 1 column(s)
-#
-create table t1 (i int, j int);
-insert t1 values (1,1),(2,2);
-create view v1 as select (2, 3) not in (select i, j from t1);
-select * from v1;
-show create view v1;
-drop view v1;
-drop table t1;
-
--echo #
--echo # MDEV-10704: Assertion `field->field->table == table_arg'
--echo # failed in fill_record(THD*, TABLE*, List<Item>&, List<Item>&,
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index f3f50fdb2d0..37089f6dec6 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -321,6 +321,7 @@ my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds
sub suite_timeout { return $opt_suite_timeout * 60; };
my $opt_wait_all;
+my $opt_wait_for_pos_timeout;
my $opt_user_args;
my $opt_repeat= 1;
my $opt_retry= 1;
@@ -1229,6 +1230,7 @@ sub command_line_setup {
'verbose+' => \$opt_verbose,
'verbose-restart' => \&report_option,
'sleep=i' => \$opt_sleep,
+ 'wait-for-pos-timeout=i' => \$opt_wait_for_pos_timeout,
'start-dirty' => \$opt_start_dirty,
'start-and-exit' => \$opt_start_exit,
'start' => \$opt_start,
@@ -1677,6 +1679,16 @@ sub command_line_setup {
$opt_shutdown_timeout= 24 * 60;
# One day for PID file creation (this is given in seconds not minutes)
$opt_start_timeout= 24 * 60 * 60;
+ if ($opt_rr && open(my $fh, '<', '/proc/sys/kernel/perf_event_paranoid'))
+ {
+ my $perf_event_paranoid= <$fh>;
+ close $fh;
+ chomp $perf_event_paranoid;
+ if ($perf_event_paranoid == 0)
+ {
+ mtr_error("rr requires kernel.perf_event_paranoid set to 1");
+ }
+ }
}
mtr_verbose("ASAN_OPTIONS=$ENV{ASAN_OPTIONS}");
@@ -2356,7 +2368,8 @@ sub environment_setup {
$ENV{'MARIADB_CONV'}= $exe_mariadb_conv;
if(IS_WINDOWS)
{
- $ENV{'MYSQL_INSTALL_DB_EXE'}= mtr_exe_exists("$bindir/sql$opt_vs_config/mysql_install_db");
+ $ENV{'MYSQL_INSTALL_DB_EXE'}= mtr_exe_exists("$bindir/sql$opt_vs_config/mysql_install_db",
+ "$bindir/bin/mysql_install_db");
}
my $client_config_exe=
@@ -5823,11 +5836,15 @@ sub start_mysqltest ($) {
mtr_add_arg($args, "--sleep=%d", $opt_sleep);
}
- if ( $opt_valgrind )
+ if ( $opt_valgrind || $opt_wait_for_pos_timeout)
{
- # We are running server under valgrind, which causes some replication
- # test to be much slower, notable rpl_mdev6020. Increase timeout.
- mtr_add_arg($args, "--wait-for-pos-timeout=1500");
+ if (! $opt_wait_for_pos_timeout)
+ {
+ # We are running server under valgrind, which causes some replication
+ # test to be much slower, notable rpl_mdev6020. Increase timeout.
+ $opt_wait_for_pos_timeout= 1500;
+ }
+ mtr_add_arg($args, "--wait-for-pos-timeout=$opt_wait_for_pos_timeout");
}
if ( $opt_ssl )
@@ -6455,7 +6472,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 mariadbd(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
@@ -6562,6 +6579,7 @@ Misc options
the file (for buildbot)
sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
+ wait-for-pos-timeout=NUM Passed to mysqltest
debug-sync-timeout=NUM Set default timeout for WAIT_FOR debug sync
actions. Disable facility with NUM=0.
gcov Collect coverage information after the test.
diff --git a/mysql-test/std_data/mysql57user.MYD b/mysql-test/std_data/mysql57user.MYD
new file mode 100644
index 00000000000..0fe0eef8d2a
--- /dev/null
+++ b/mysql-test/std_data/mysql57user.MYD
Binary files differ
diff --git a/mysql-test/std_data/mysql57user.MYI b/mysql-test/std_data/mysql57user.MYI
new file mode 100644
index 00000000000..16e9fa662a3
--- /dev/null
+++ b/mysql-test/std_data/mysql57user.MYI
Binary files differ
diff --git a/mysql-test/std_data/mysql57user.frm b/mysql-test/std_data/mysql57user.frm
new file mode 100644
index 00000000000..2ae83ceb606
--- /dev/null
+++ b/mysql-test/std_data/mysql57user.frm
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test.MYD b/mysql-test/std_data/mysql_json/mysql_json_test.MYD
new file mode 100644
index 00000000000..0be8c5968b4
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test.MYD
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test.MYI b/mysql-test/std_data/mysql_json/mysql_json_test.MYI
new file mode 100644
index 00000000000..ada3ff23836
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test.MYI
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test.frm b/mysql-test/std_data/mysql_json/mysql_json_test.frm
new file mode 100644
index 00000000000..94c642f45ac
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test.frm
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test_big.MYD b/mysql-test/std_data/mysql_json/mysql_json_test_big.MYD
new file mode 100644
index 00000000000..21b1fffc4ba
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test_big.MYD
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test_big.MYI b/mysql-test/std_data/mysql_json/mysql_json_test_big.MYI
new file mode 100644
index 00000000000..79a1d9ebd89
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test_big.MYI
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/mysql_json_test_big.frm b/mysql-test/std_data/mysql_json/mysql_json_test_big.frm
new file mode 100644
index 00000000000..94c642f45ac
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/mysql_json_test_big.frm
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/tempty.MYD b/mysql-test/std_data/mysql_json/tempty.MYD
new file mode 100644
index 00000000000..b4bf921b99f
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/tempty.MYD
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/tempty.MYI b/mysql-test/std_data/mysql_json/tempty.MYI
new file mode 100644
index 00000000000..003b7c8842f
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/tempty.MYI
Binary files differ
diff --git a/mysql-test/std_data/mysql_json/tempty.frm b/mysql-test/std_data/mysql_json/tempty.frm
new file mode 100644
index 00000000000..15e6955dfb3
--- /dev/null
+++ b/mysql-test/std_data/mysql_json/tempty.frm
Binary files differ
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
index 3e400d4f272..1cfb6bce801 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
@@ -349,6 +349,11 @@ a
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*/;
@@ -5358,3 +5363,92 @@ START TRANSACTION
#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
Error: Found Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value.
+/*!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*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 4:46:40
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list [0-1-323]
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000002
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000003
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-324 ddl
+/*!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=324*//*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0/*!*/;
+SET @@session.sql_mode=1411383296/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+CREATE TABLE t1 (a GEOMETRY DEFAULT NULL)
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-325
+/*!100001 SET @@session.gtid_seq_no=325*//*!*/;
+START TRANSACTION
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
+#Q> INSERT INTO t1 VALUES (NULL)
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=NULL /* GEOMETRY meta=4 nullable=1 is_null=1 */
+# Number of rows: 1
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-326
+/*!100001 SET @@session.gtid_seq_no=326*//*!*/;
+START TRANSACTION
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
+#Q> INSERT INTO t1 VALUES (POINT(10,10))
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX 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 */
+# Number of rows: 1
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-327 ddl
+/*!100001 SET @@session.gtid_seq_no=327*//*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX 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 # CRC32 XXX Rotate to master-bin.000004 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
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..c3a1af2f9c4
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_recover_checksum_error.result
@@ -0,0 +1,8 @@
+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");
+# restart: --master_verify_checksum=ON --debug_dbug=+d,corrupt_read_log_event_char
+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/t/binlog_mysqlbinlog_row.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
index add977bf07a..b366578f3cd 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
@@ -465,6 +465,17 @@ 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/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
@@ -475,3 +486,6 @@ flush logs;
--error 1
--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000002 2>&1
+--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/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
+--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000003
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/compat/oracle/r/sp-package.result b/mysql-test/suite/compat/oracle/r/sp-package.result
index 4f0f05b1939..e7ab4eaa4a2 100644
--- a/mysql-test/suite/compat/oracle/r/sp-package.result
+++ b/mysql-test/suite/compat/oracle/r/sp-package.result
@@ -249,7 +249,11 @@ RETURN f2();
END;
END;
$$
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
DROP PACKAGE test2;
#
# Broken CREATE PACKAGE at a package function call time
@@ -271,11 +275,23 @@ UPDATE mysql.proc SET `body`='garbage'
WHERE db='test' AND name='test2' AND type='PACKAGE';
# sp-cache-invalidate
SELECT test2.f1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
SELECT test2.f1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
SELECT test2.f1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
DROP PACKAGE test2;
#
# Broken CREATE PACKAGE at a package procedure call time
@@ -297,11 +313,23 @@ UPDATE mysql.proc SET `body`='garbage'
WHERE db='test' AND name='test2' AND type='PACKAGE';
# sp-cache-invalidate
CALL test2.p1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
CALL test2.p1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
CALL test2.p1();
-ERROR HY000: Failed to load routine test.test2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
+ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
+show warnings;
+Level Code Message
+Error 1064 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 'garbage' at line 1
+Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS
DROP PACKAGE test2;
#
# Bad routine names
diff --git a/mysql-test/suite/compat/oracle/t/sp-package.test b/mysql-test/suite/compat/oracle/t/sp-package.test
index 5eac3987982..96420c18820 100644
--- a/mysql-test/suite/compat/oracle/t/sp-package.test
+++ b/mysql-test/suite/compat/oracle/t/sp-package.test
@@ -335,6 +335,7 @@ CREATE PACKAGE BODY test2 AS
END;
$$
DELIMITER ;$$
+show warnings;
DROP PACKAGE test2;
@@ -367,10 +368,13 @@ UPDATE mysql.proc SET `body`='garbage'
--source sp-cache-invalidate.inc
--error ER_SP_PROC_TABLE_CORRUPT
SELECT test2.f1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
SELECT test2.f1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
SELECT test2.f1();
+show warnings;
DROP PACKAGE test2;
@@ -403,10 +407,13 @@ UPDATE mysql.proc SET `body`='garbage'
--source sp-cache-invalidate.inc
--error ER_SP_PROC_TABLE_CORRUPT
CALL test2.p1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
CALL test2.p1();
+show warnings;
--error ER_SP_PROC_TABLE_CORRUPT
CALL test2.p1();
+show warnings;
DROP PACKAGE test2;
diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result b/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result
index 86d0fecd2e8..9ebac86335e 100644
--- a/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result
+++ b/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result
@@ -41,6 +41,14 @@ call innodb_insert_proc(2000);
insert into innodb_compact select * from innodb_normal;
insert into innodb_dynamic select * from innodb_normal;
commit;
+FLUSH TABLES innodb_compact FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT;
+UNLOCK TABLES;
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED';
+variable_value > 0
+1
# restart: --innodb-encrypt-tables=OFF
set global innodb_compression_algorithm = 1;
alter table innodb_normal engine=innodb page_compressed=DEFAULT;
@@ -64,6 +72,16 @@ innodb_dynamic CREATE TABLE `innodb_dynamic` (
`c1` bigint(20) NOT NULL,
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+FLUSH TABLES innodb_normal FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT;
+UNLOCK TABLES;
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_PAGE_DECOMPRESSED';
+variable_value > 0
+1
drop procedure innodb_insert_proc;
drop table innodb_normal;
drop table innodb_compact;
diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result b/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result
index 4be73459cfd..e46b4a0ed6f 100644
--- a/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result
+++ b/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result
@@ -37,41 +37,44 @@ innodb_redundant CREATE TABLE `innodb_redundant` (
`c1` bigint(20) NOT NULL,
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4
-create procedure innodb_insert_proc (repeat_count int)
-begin
-declare current_num int;
-set current_num = 0;
-while current_num < repeat_count do
-insert into innodb_normal values(current_num, substring(MD5(RAND()), -64));
-set current_num = current_num + 1;
-end while;
-end//
-commit;
-begin;
-call innodb_insert_proc(2000);
-insert into innodb_compact select * from innodb_normal;
-insert into innodb_compressed select * from innodb_normal;
-insert into innodb_dynamic select * from innodb_normal;
-insert into innodb_redundant select * from innodb_normal;
-commit;
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
+FLUSH TABLES innodb_normal FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT;
+UNLOCK TABLES;
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
variable_value > 0
1
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
-variable_value >= 0
-1
# restart
-update innodb_normal set c1 = c1 +1;
-update innodb_compact set c1 = c1 + 1;
-update innodb_compressed set c1 = c1 + 1;
-update innodb_dynamic set c1 = c1 + 1;
-update innodb_redundant set c1 = c1 + 1;
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-variable_value > 0
-1
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
-variable_value > 0
-1
+BEGIN;
+INSERT INTO innodb_normal SET c1 = 1;
+INSERT INTO innodb_compact SET c1 = 1;
+INSERT INTO innodb_compressed SET c1 = 1;
+INSERT INTO innodb_dynamic SET c1 = 1;
+INSERT INTO innodb_redundant SET c1 = 1;
+COMMIT;
+FLUSH TABLES innodb_normal FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT;
+UNLOCK TABLES;
+select variable_name from information_schema.global_status
+where variable_value > 0 and variable_name
+IN ('INNODB_NUM_PAGES_ENCRYPTED','INNODB_NUM_PAGES_DECRYPTED');
+variable_name
+INNODB_NUM_PAGES_ENCRYPTED
+INNODB_NUM_PAGES_DECRYPTED
SET GLOBAL innodb_encrypt_tables=OFF;
alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT;
show create table innodb_compact;
@@ -101,13 +104,16 @@ innodb_redundant CREATE TABLE `innodb_redundant` (
`c1` bigint(20) NOT NULL,
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-variable_value >= 0
-1
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
-variable_value >= 0
-1
-drop procedure innodb_insert_proc;
+FLUSH TABLES innodb_normal FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT;
+UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT;
+UNLOCK TABLES;
drop table innodb_normal;
drop table innodb_compact;
drop table innodb_compressed;
diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result
index d08cb33e0fc..2c2f52d4d64 100644
--- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result
+++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result
@@ -4,6 +4,3963 @@
select @@encrypt_tmp_files;
@@encrypt_tmp_files
1
+drop table if exists t1,t2;
+drop view if exists v1;
+# ########################################################################
+# # Parser tests
+# ########################################################################
+#
+# Check what happens when one attempts to use window function without OVER clause
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+select row_number() from t1;
+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 'from t1' at line 1
+select rank() from t1;
+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 'from t1' at line 1
+# Attempt to use window function in the WHERE clause
+select * from t1 where 1=rank() over (order by a);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+select * from t1 where 1>row_number() over (partition by b order by a);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+drop table t1;
+# ########################################################################
+# # Functionality tests
+# ########################################################################
+#
+# Check if ROW_NUMBER() works in basic cases
+create table t1(a int, b int, x char(32));
+insert into t1 values (2, 10, 'xx');
+insert into t1 values (2, 10, 'zz');
+insert into t1 values (2, 20, 'yy');
+insert into t1 values (3, 10, 'xxx');
+insert into t1 values (3, 20, 'vvv');
+select a, row_number() over (partition by a order by b) from t1;
+a row_number() over (partition by a order by b)
+2 1
+2 2
+2 3
+3 1
+3 2
+select a, b, x, row_number() over (partition by a order by x) from t1;
+a b x row_number() over (partition by a order by x)
+2 10 xx 1
+2 20 yy 2
+2 10 zz 3
+3 20 vvv 1
+3 10 xxx 2
+drop table t1;
+create table t1 (pk int primary key, a int, b int);
+insert into t1 values
+(1, 10, 22),
+(2, 11, 21),
+(3, 12, 20),
+(4, 13, 19),
+(5, 14, 18);
+select
+pk, a, b,
+row_number() over (order by a),
+row_number() over (order by b)
+from t1
+order by b;
+pk a b row_number() over (order by a) row_number() over (order by b)
+5 14 18 5 1
+4 13 19 4 2
+3 12 20 3 3
+2 11 21 2 4
+1 10 22 1 5
+drop table t1;
+#
+# Try RANK() function
+#
+create table t2 (
+pk int primary key,
+a int
+);
+insert into t2 values
+( 1 , 0),
+( 2 , 0),
+( 3 , 1),
+( 4 , 1),
+( 8 , 2),
+( 5 , 2),
+( 6 , 2),
+( 7 , 2),
+( 9 , 4),
+(10 , 4);
+select pk, a, rank() over (order by a) from t2;
+pk a rank() over (order by a)
+1 0 1
+10 4 9
+2 0 1
+3 1 3
+4 1 3
+5 2 5
+6 2 5
+7 2 5
+8 2 5
+9 4 9
+select pk, a, rank() over (order by a desc) from t2;
+pk a rank() over (order by a desc)
+1 0 9
+10 4 1
+2 0 9
+3 1 7
+4 1 7
+5 2 3
+6 2 3
+7 2 3
+8 2 3
+9 4 1
+drop table t2;
+#
+# Try Aggregates as window functions. With frames.
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+pk c
+1 1
+2 1
+3 1
+4 1
+5 2
+6 2
+7 2
+8 2
+9 2
+10 2
+select
+pk, c,
+count(*) over (partition by c order by pk
+rows between 2 preceding and 2 following) as CNT
+from t1;
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over (partition by c order by pk
+rows between 1 preceding and 2 following) as CNT
+from t1;
+pk c CNT
+1 1 3
+2 1 4
+3 1 3
+4 1 2
+5 2 3
+6 2 4
+7 2 4
+8 2 4
+9 2 3
+10 2 2
+select
+pk, c,
+count(*) over (partition by c order by pk
+rows between 2 preceding and current row) as CNT
+from t1;
+pk c CNT
+1 1 1
+2 1 2
+3 1 3
+4 1 3
+5 2 1
+6 2 2
+7 2 3
+8 2 3
+9 2 3
+10 2 3
+select
+pk,c,
+count(*) over (partition by c order by pk rows
+between 1 following and 2 following) as CNT
+from t1;
+pk c CNT
+1 1 2
+2 1 2
+3 1 1
+4 1 0
+5 2 2
+6 2 2
+7 2 2
+8 2 2
+9 2 1
+10 2 0
+select
+pk,c,
+count(*) over (partition by c order by pk rows
+between 2 preceding and 1 preceding) as CNT
+from t1;
+pk c CNT
+1 1 0
+2 1 1
+3 1 2
+4 1 2
+5 2 0
+6 2 1
+7 2 2
+8 2 2
+9 2 2
+10 2 2
+select
+pk, c,
+count(*) over (partition by c order by pk
+rows between current row and 1 following) as CNT
+from t1;
+pk c CNT
+1 1 2
+2 1 2
+3 1 2
+4 1 1
+5 2 2
+6 2 2
+7 2 2
+8 2 2
+9 2 2
+10 2 1
+# Check ORDER BY DESC
+select
+pk, c,
+count(*) over (partition by c order by pk desc
+rows between 2 preceding and 2 following) as CNT
+from t1;
+pk c CNT
+4 1 3
+3 1 4
+2 1 4
+1 1 3
+10 2 3
+9 2 4
+8 2 5
+7 2 5
+6 2 4
+5 2 3
+drop table t0,t1;
+#
+# Resolution of window names
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+pk c
+1 1
+2 1
+3 1
+4 1
+5 2
+6 2
+7 2
+8 2
+9 2
+10 2
+select
+pk, c,
+count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+rows between 2 preceding and 2 following);
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over (w1 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c order by pk);
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over (w1 order by pk rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c);
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 order by pk);
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over w3 as CNT
+from t1
+window
+w1 as (partition by c),
+w2 as (w1 order by pk),
+w3 as (w2 rows between 2 preceding and 2 following);
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+select
+pk, c,
+count(*) over w as CNT
+from t1
+window w1 as (partition by c order by pk
+rows between 2 preceding and 2 following);
+ERROR HY000: Window specification with name 'w' is not defined
+select
+pk, c,
+count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w1 as (order by pk);
+ERROR HY000: Multiple window specifications with the same name 'w1'
+select
+pk, c,
+count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w partition by c order by pk);
+ERROR HY000: Window specification with name 'w' is not defined
+select
+pk, c,
+count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 partition by c order by pk);
+ERROR HY000: Window specification referencing another one 'w1' cannot contain partition list
+select
+pk, c,
+count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c order by pk), w2 as (w1 order by pk);
+ERROR HY000: Referenced window specification 'w1' already contains order list
+select
+pk, c,
+count(*) over w3 as CNT
+from t1
+window
+w1 as (partition by c),
+w2 as (w1 order by pk rows between 3 preceding and 2 following),
+w3 as (w2 rows between 2 preceding and 2 following);
+ERROR HY000: Referenced window specification 'w2' cannot contain window frame
+select
+pk, c,
+count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+rows between unbounded following and 2 following);
+ERROR HY000: Unacceptable combination of window frame bound specifications
+select
+pk, c,
+count(*) over (w1 rows between 2 preceding and unbounded preceding) as CNT
+from t1
+window w1 as (partition by c order by pk);
+ERROR HY000: Unacceptable combination of window frame bound specifications
+select
+pk, c,
+count(*) over (w1 order by pk rows between current row and 2 preceding) as CNT
+from t1
+window w1 as (partition by c);
+ERROR HY000: Unacceptable combination of window frame bound specifications
+select
+pk, c,
+count(*) over (w2 rows between 2 following and current row) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 order by pk);
+ERROR HY000: Unacceptable combination of window frame bound specifications
+select
+pk, c
+from t1 where rank() over w1 > 2
+window w1 as (partition by c order by pk);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+select
+c, max(pk) as m
+from t1
+group by c + rank() over w1
+window w1 as (order by m);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+select
+c, max(pk) as m, rank() over w1 as r
+from t1
+group by c+r
+window w1 as (order by m);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+select
+c, max(pk) as m, rank() over w1 as r
+from t1
+group by c having c+r > 3
+window w1 as (order by m);
+ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause
+select
+c, max(pk) as m, rank() over w1 as r,
+rank() over (partition by r+1 order by m)
+from t1
+group by c
+window w1 as (order by m);
+ERROR HY000: Window function is not allowed in window specification
+select
+c, max(pk) as m, rank() over w1 as r,
+rank() over (partition by m order by r)
+from t1
+group by c
+window w1 as (order by m);
+ERROR HY000: Window function is not allowed in window specification
+select
+c, max(pk) as m, rank() over w1 as r, dense_rank() over w2 as dr
+from t1
+group by c
+window w1 as (order by m), w2 as (partition by r order by m);
+ERROR HY000: Window function is not allowed in window specification
+select
+pk, c,
+row_number() over (partition by c order by pk
+range between unbounded preceding and current row) as r
+from t1;
+ERROR HY000: Window frame is not allowed with 'row_number'
+select
+pk, c,
+rank() over w1 as r
+from t1
+window w1 as (partition by c order by pk
+rows between 2 preceding and 2 following);
+ERROR HY000: Window frame is not allowed with 'rank'
+select
+pk, c,
+dense_rank() over (partition by c order by pk
+rows between 1 preceding and 1 following) as r
+from t1;
+ERROR HY000: Window frame is not allowed with 'dense_rank'
+select
+pk, c,
+rank() over w1 as r
+from t1
+window w1 as (partition by c);
+ERROR HY000: No order list in window specification for 'rank'
+select
+pk, c,
+dense_rank() over (partition by c) as r
+from t1;
+ERROR HY000: No order list in window specification for 'dense_rank'
+drop table t0,t1;
+#
+# MDEV-9634: Window function produces incorrect value
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (part_id int, pk int, a int);
+insert into t2 select
+if(a<5, 0, 1), a, if(a<5, NULL, 1) from t0;
+select * from t2;
+part_id pk a
+0 0 NULL
+0 1 NULL
+0 2 NULL
+0 3 NULL
+0 4 NULL
+1 5 1
+1 6 1
+1 7 1
+1 8 1
+1 9 1
+select
+part_id, pk, a,
+count(a) over (partition by part_id order by pk
+rows between 1 preceding and 1 following) as CNT
+from t2;
+part_id pk a CNT
+0 0 NULL 0
+0 1 NULL 0
+0 2 NULL 0
+0 3 NULL 0
+0 4 NULL 0
+1 5 1 2
+1 6 1 3
+1 7 1 3
+1 8 1 3
+1 9 1 2
+drop table t0, t2;
+#
+# RANGE-type bounds
+#
+create table t3 (
+pk int,
+val int
+);
+insert into t3 values
+(0, 1),
+(1, 1),
+(2, 1),
+(3, 2),
+(4, 2),
+(5, 2),
+(6, 2);
+select
+val,
+count(val) over (order by val
+range between current row and
+current row)
+as CNT
+from t3;
+val CNT
+1 3
+1 3
+1 3
+2 4
+2 4
+2 4
+2 4
+insert into t3 values
+(7, 3),
+(8, 3);
+select
+val,
+count(val) over (order by val
+range between current row and
+current row)
+as CNT
+from t3;
+val CNT
+1 3
+1 3
+1 3
+2 4
+2 4
+2 4
+2 4
+3 2
+3 2
+drop table t3;
+# Now, check with PARTITION BY
+create table t4 (
+part_id int,
+pk int,
+val int
+);
+insert into t4 values
+(1234, 100, 1),
+(1234, 101, 1),
+(1234, 102, 1),
+(1234, 103, 2),
+(1234, 104, 2),
+(1234, 105, 2),
+(1234, 106, 2),
+(1234, 107, 3),
+(1234, 108, 3),
+(5678, 200, 1),
+(5678, 201, 1),
+(5678, 202, 1),
+(5678, 203, 2),
+(5678, 204, 2),
+(5678, 205, 2),
+(5678, 206, 2),
+(5678, 207, 3),
+(5678, 208, 3);
+select
+part_id,
+val,
+count(val) over (partition by part_id
+order by val
+range between current row and
+current row)
+as CNT
+from t4;
+part_id val CNT
+1234 1 3
+1234 1 3
+1234 1 3
+1234 2 4
+1234 2 4
+1234 2 4
+1234 2 4
+1234 3 2
+1234 3 2
+5678 1 3
+5678 1 3
+5678 1 3
+5678 2 4
+5678 2 4
+5678 2 4
+5678 2 4
+5678 3 2
+5678 3 2
+#
+# Try RANGE UNBOUNDED PRECEDING | FOLLOWING
+#
+select
+part_id,
+val,
+count(val) over (partition by part_id
+order by val
+range between unbounded preceding and
+current row)
+as CNT
+from t4;
+part_id val CNT
+1234 1 3
+1234 1 3
+1234 1 3
+1234 2 7
+1234 2 7
+1234 2 7
+1234 2 7
+1234 3 9
+1234 3 9
+5678 1 3
+5678 1 3
+5678 1 3
+5678 2 7
+5678 2 7
+5678 2 7
+5678 2 7
+5678 3 9
+5678 3 9
+select
+part_id,
+val,
+count(val) over (partition by part_id
+order by val
+range between current row and
+unbounded following)
+as CNT
+from t4;
+part_id val CNT
+1234 1 9
+1234 1 9
+1234 1 9
+1234 2 6
+1234 2 6
+1234 2 6
+1234 2 6
+1234 3 2
+1234 3 2
+5678 1 9
+5678 1 9
+5678 1 9
+5678 2 6
+5678 2 6
+5678 2 6
+5678 2 6
+5678 3 2
+5678 3 2
+select
+part_id,
+val,
+count(val) over (partition by part_id
+order by val
+range between unbounded preceding and
+unbounded following)
+as CNT
+from t4;
+part_id val CNT
+1234 1 9
+1234 1 9
+1234 1 9
+1234 2 9
+1234 2 9
+1234 2 9
+1234 2 9
+1234 3 9
+1234 3 9
+5678 1 9
+5678 1 9
+5678 1 9
+5678 2 9
+5678 2 9
+5678 2 9
+5678 2 9
+5678 3 9
+5678 3 9
+drop table t4;
+#
+# MDEV-9695: Wrong window frame when using RANGE BETWEEN N FOLLOWING AND PRECEDING
+#
+create table t1 (pk int, a int, b int);
+insert into t1 values
+( 1 , 0, 1),
+( 2 , 0, 2),
+( 3 , 1, 4),
+( 4 , 1, 8),
+( 5 , 2, 32),
+( 6 , 2, 64),
+( 7 , 2, 128),
+( 8 , 2, 16);
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as bit_or
+from t1;
+pk a b bit_or
+1 0 1 3
+2 0 2 3
+3 1 4 12
+4 1 8 12
+5 2 32 96
+6 2 64 224
+7 2 128 208
+8 2 16 144
+# Extra ROWS n PRECEDING tests
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or
+from t1;
+pk a b bit_or
+1 0 1 0
+2 0 2 1
+3 1 4 0
+4 1 8 4
+5 2 32 0
+6 2 64 32
+7 2 128 64
+8 2 16 128
+drop table t1;
+create table t2 (
+pk int,
+a int,
+b int
+);
+insert into t2 values
+( 1, 0, 1),
+( 2, 0, 2),
+( 3, 0, 4),
+( 4, 0, 8),
+( 5, 1, 16),
+( 6, 1, 32),
+( 7, 1, 64),
+( 8, 1, 128),
+( 9, 2, 256),
+(10, 2, 512),
+(11, 2, 1024),
+(12, 2, 2048);
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or
+from t2;
+pk a b bit_or
+1 0 1 0
+2 0 2 1
+3 0 4 2
+4 0 8 4
+5 1 16 0
+6 1 32 16
+7 1 64 32
+8 1 128 64
+9 2 256 0
+10 2 512 256
+11 2 1024 512
+12 2 2048 1024
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) as bit_or
+from t2;
+pk a b bit_or
+1 0 1 0
+2 0 2 0
+3 0 4 1
+4 0 8 2
+5 1 16 0
+6 1 32 0
+7 1 64 16
+8 1 128 32
+9 2 256 0
+10 2 512 0
+11 2 1024 256
+12 2 2048 512
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) as bit_or
+from t2;
+pk a b bit_or
+1 0 1 0
+2 0 2 1
+3 0 4 3
+4 0 8 6
+5 1 16 0
+6 1 32 16
+7 1 64 48
+8 1 128 96
+9 2 256 0
+10 2 512 256
+11 2 1024 768
+12 2 2048 1536
+# Check CURRENT ROW
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN CURRENT ROW AND CURRENT ROW) as bit_or
+from t2;
+pk a b bit_or
+1 0 1 1
+2 0 2 2
+3 0 4 4
+4 0 8 8
+5 1 16 16
+6 1 32 32
+7 1 64 64
+8 1 128 128
+9 2 256 256
+10 2 512 512
+11 2 1024 1024
+12 2 2048 2048
+drop table t2;
+#
+# Try RANGE PRECEDING|FOLLWING n
+#
+create table t1 (
+part_id int,
+pk int,
+a int
+);
+insert into t1 values
+(10, 1, 1),
+(10, 2, 2),
+(10, 3, 4),
+(10, 4, 8),
+(10, 5,26),
+(10, 6,27),
+(10, 7,40),
+(10, 8,71),
+(10, 9,72);
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 10 FOLLOWING) as cnt
+from t1;
+pk a cnt
+1 1 4
+2 2 4
+3 4 4
+4 8 4
+5 26 6
+6 27 6
+7 40 7
+8 71 9
+9 72 9
+select
+pk, a,
+count(a) over (ORDER BY a DESC
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 10 FOLLOWING) as cnt
+from t1;
+pk a cnt
+9 72 2
+8 71 2
+7 40 3
+6 27 5
+5 26 5
+4 8 9
+3 4 9
+2 2 9
+1 1 9
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 1 FOLLOWING) as cnt
+from t1;
+pk a cnt
+1 1 2
+2 2 2
+3 4 3
+4 8 4
+5 26 6
+6 27 6
+7 40 7
+8 71 9
+9 72 9
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 10 PRECEDING) as cnt
+from t1;
+pk a cnt
+1 1 0
+2 2 0
+3 4 0
+4 8 0
+5 26 4
+6 27 4
+7 40 6
+8 71 7
+9 72 7
+select
+pk, a,
+count(a) over (ORDER BY a DESC
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 10 PRECEDING) as cnt
+from t1;
+pk a cnt
+9 72 0
+8 71 0
+7 40 2
+6 27 3
+5 26 3
+4 8 5
+3 4 5
+2 2 5
+1 1 5
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 1 PRECEDING) as cnt
+from t1;
+pk a cnt
+1 1 0
+2 2 1
+3 4 2
+4 8 3
+5 26 4
+6 27 5
+7 40 6
+8 71 7
+9 72 8
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN 1 PRECEDING
+AND CURRENT ROW) as cnt
+from t1;
+pk a cnt
+1 1 1
+2 2 2
+3 4 1
+4 8 1
+5 26 1
+6 27 2
+7 40 1
+8 71 1
+9 72 2
+select
+pk, a,
+count(a) over (ORDER BY a DESC
+RANGE BETWEEN 1 PRECEDING
+AND CURRENT ROW) as cnt
+from t1;
+pk a cnt
+9 72 1
+8 71 2
+7 40 1
+6 27 1
+5 26 2
+4 8 1
+3 4 1
+2 2 1
+1 1 2
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN 1 FOLLOWING
+AND 3 FOLLOWING) as cnt
+from t1;
+pk a cnt
+1 1 2
+2 2 1
+3 4 0
+4 8 0
+5 26 1
+6 27 0
+7 40 0
+8 71 1
+9 72 0
+# Try CURRENT ROW with[out] DESC
+select
+pk, a,
+count(a) over (ORDER BY a
+RANGE BETWEEN CURRENT ROW
+AND 1 FOLLOWING) as cnt
+from t1;
+pk a cnt
+1 1 2
+2 2 1
+3 4 1
+4 8 1
+5 26 2
+6 27 1
+7 40 1
+8 71 2
+9 72 1
+select
+pk, a,
+count(a) over (order by a desc
+range between current row
+and 1 following) as cnt
+from t1;
+pk a cnt
+9 72 2
+8 71 1
+7 40 1
+6 27 2
+5 26 1
+4 8 1
+3 4 1
+2 2 2
+1 1 1
+insert into t1 select 22, pk, a from t1;
+select
+part_id, pk, a,
+count(a) over (PARTITION BY part_id
+ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 10 FOLLOWING) as cnt
+from t1;
+part_id pk a cnt
+10 1 1 4
+10 2 2 4
+10 3 4 4
+10 4 8 4
+10 5 26 6
+10 6 27 6
+10 7 40 7
+10 8 71 9
+10 9 72 9
+22 1 1 4
+22 2 2 4
+22 3 4 4
+22 4 8 4
+22 5 26 6
+22 6 27 6
+22 7 40 7
+22 8 71 9
+22 9 72 9
+select
+pk, a,
+count(a) over (PARTITION BY part_id
+ORDER BY a
+RANGE BETWEEN UNBOUNDED PRECEDING
+AND 1 PRECEDING) as cnt
+from t1;
+pk a cnt
+1 1 0
+2 2 1
+3 4 2
+4 8 3
+5 26 4
+6 27 5
+7 40 6
+8 71 7
+9 72 8
+1 1 0
+2 2 1
+3 4 2
+4 8 3
+5 26 4
+6 27 5
+7 40 6
+8 71 7
+9 72 8
+drop table t1;
+# Try a RANGE frame over non-integer datatype:
+create table t1 (
+col1 int,
+a decimal(5,3)
+);
+insert into t1 values (1, 0.45);
+insert into t1 values (1, 0.5);
+insert into t1 values (1, 0.55);
+insert into t1 values (1, 1.21);
+insert into t1 values (1, 1.22);
+insert into t1 values (1, 3.33);
+select
+a,
+count(col1) over (order by a
+range between 0.1 preceding
+and 0.1 following)
+from t1;
+a count(col1) over (order by a
+range between 0.1 preceding
+and 0.1 following)
+0.450 3
+0.500 3
+0.550 3
+1.210 2
+1.220 2
+3.330 1
+drop table t1;
+#
+# RANGE-type frames and NULL values
+#
+create table t1 (
+pk int,
+a int,
+b int
+);
+insert into t1 values (1, NULL,1);
+insert into t1 values (2, NULL,1);
+insert into t1 values (3, NULL,1);
+insert into t1 values (4, 10 ,1);
+insert into t1 values (5, 11 ,1);
+insert into t1 values (6, 12 ,1);
+insert into t1 values (7, 13 ,1);
+insert into t1 values (8, 14 ,1);
+select
+pk, a,
+count(b) over (order by a
+range between 2 preceding
+and 2 following) as CNT
+from t1
+order by a, pk;
+pk a CNT
+1 NULL 3
+2 NULL 3
+3 NULL 3
+4 10 3
+5 11 4
+6 12 5
+7 13 4
+8 14 3
+drop table t1;
+#
+# Try ranges that have bound1 > bound2. The standard actually allows them
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+pk c
+1 1
+2 1
+3 1
+4 1
+5 2
+6 2
+7 2
+8 2
+9 2
+10 2
+select
+pk, c,
+count(*) over (partition by c
+order by pk
+rows between 1 preceding
+and 2 preceding)
+as cnt
+from t1;
+pk c cnt
+1 1 0
+2 1 0
+3 1 0
+4 1 0
+5 2 0
+6 2 0
+7 2 0
+8 2 0
+9 2 0
+10 2 0
+select
+pk, c,
+sum(c) over (partition by c
+order by pk
+rows between 1 preceding
+and 2 preceding)
+as sum
+from t1;
+pk c sum
+1 1 NULL
+2 1 NULL
+3 1 NULL
+4 1 NULL
+5 2 NULL
+6 2 NULL
+7 2 NULL
+8 2 NULL
+9 2 NULL
+10 2 NULL
+select
+pk, c,
+sum(c) over (partition by c
+order by pk
+rows between 2 following
+and 1 following)
+as sum
+from t1;
+pk c sum
+1 1 NULL
+2 1 NULL
+3 1 NULL
+4 1 NULL
+5 2 NULL
+6 2 NULL
+7 2 NULL
+8 2 NULL
+9 2 NULL
+10 2 NULL
+select
+pk, c,
+count(*) over (partition by c
+order by pk
+range between 1 preceding
+and 2 preceding)
+as cnt
+from t1;
+pk c cnt
+1 1 0
+2 1 0
+3 1 0
+4 1 0
+5 2 0
+6 2 0
+7 2 0
+8 2 0
+9 2 0
+10 2 0
+drop table t0, t1;
+#
+# Error checking for frame bounds
+#
+create table t1 (a int, b int, c varchar(32));
+insert into t1 values (1,1,'foo');
+insert into t1 values (2,2,'bar');
+select
+count(*) over (order by a,b
+range between unbounded preceding and current row)
+from t1;
+ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key
+select
+count(*) over (order by c
+range between unbounded preceding and current row)
+from t1;
+ERROR HY000: Numeric datatype is required for RANGE-type frame
+select
+count(*) over (order by a
+range between 'abcd' preceding and current row)
+from t1;
+ERROR HY000: Numeric datatype is required for RANGE-type frame
+select
+count(*) over (order by a
+range between current row and 'foo' following)
+from t1;
+ERROR HY000: Numeric datatype is required for RANGE-type frame
+# Try range frame with invalid bounds
+select
+count(*) over (order by a
+rows between 0.5 preceding and current row)
+from t1;
+ERROR HY000: Integer is required for ROWS-type frame
+select
+count(*) over (order by a
+rows between current row and 3.14 following)
+from t1;
+ERROR HY000: Integer is required for ROWS-type frame
+#
+# EXCLUDE clause is parsed but not supported
+#
+select
+count(*) over (order by a
+rows between 1 preceding and 1 following
+exclude current row)
+from t1;
+ERROR HY000: Frame exclusion is not supported yet
+select
+count(*) over (order by a
+range between 1 preceding and 1 following
+exclude ties)
+from t1;
+ERROR HY000: Frame exclusion is not supported yet
+select
+count(*) over (order by a
+range between 1 preceding and 1 following
+exclude group)
+from t1;
+ERROR HY000: Frame exclusion is not supported yet
+select
+count(*) over (order by a
+rows between 1 preceding and 1 following
+exclude no others)
+from t1;
+count(*) over (order by a
+rows between 1 preceding and 1 following
+exclude no others)
+2
+2
+drop table t1;
+#
+# Window function in grouping query
+#
+create table t1 (
+username varchar(32),
+amount int
+);
+insert into t1 values
+('user1',1),
+('user1',5),
+('user1',3),
+('user2',10),
+('user2',20),
+('user2',30);
+select
+username,
+sum(amount) as s,
+rank() over (order by s desc)
+from t1
+group by username;
+username s rank() over (order by s desc)
+user1 9 2
+user2 60 1
+drop table t1;
+#
+# mdev-9719: Window function in prepared statement
+#
+create table t1(a int, b int, x char(32));
+insert into t1 values (2, 10, 'xx');
+insert into t1 values (2, 10, 'zz');
+insert into t1 values (2, 20, 'yy');
+insert into t1 values (3, 10, 'xxx');
+insert into t1 values (3, 20, 'vvv');
+prepare stmt from 'select a, row_number() over (partition by a order by b) from t1';
+execute stmt;
+a row_number() over (partition by a order by b)
+2 1
+2 2
+2 3
+3 1
+3 2
+drop table t1;
+#
+# mdev-9754: Window name resolution in prepared statement
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+pk c
+1 1
+2 1
+3 1
+4 1
+5 2
+6 2
+7 2
+8 2
+9 2
+10 2
+prepare stmt from
+'select
+ pk, c,
+ count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+ rows between 2 preceding and 2 following)';
+execute stmt;
+pk c CNT
+1 1 3
+2 1 4
+3 1 4
+4 1 3
+5 2 3
+6 2 4
+7 2 5
+8 2 5
+9 2 4
+10 2 3
+drop table t0,t1;
+#
+# EXPLAIN FORMAT=JSON support for window functions
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+explain format=json select rank() over (order by a) from t0;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t0.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t0",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+create table t1 (a int, b int, c int);
+insert into t1 select a,a,a from t0;
+explain format=json
+select
+a,
+rank() over (order by sum(b))
+from t1
+group by a;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "filesort": {
+ "sort_key": "t1.a",
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "sum(t1.b)"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+}
+explain format=json
+select
+a,
+rank() over (order by sum(b))
+from t1
+group by a
+order by null;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "sum(t1.b)"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+#
+# Check how window function works together with GROUP BY and HAVING
+#
+select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7);
+b MX rank() over (order by b)
+3 3 1
+5 5 2
+7 7 3
+explain format=json
+select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "having_condition": "MX in (3,5,7)",
+ "filesort": {
+ "sort_key": "t1.b",
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.b"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+}
+drop table t1;
+drop table t0;
+#
+# Building ordering index for window functions
+#
+create table t1 (
+pk int primary key,
+a int,
+b int,
+c int
+);
+insert into t1 values
+(101 , 0, 10, 1),
+(102 , 0, 10, 2),
+(103 , 1, 10, 3),
+(104 , 1, 10, 4),
+(108 , 2, 10, 5),
+(105 , 2, 20, 6),
+(106 , 2, 20, 7),
+(107 , 2, 20, 8),
+(109 , 4, 20, 9),
+(110 , 4, 20, 10),
+(111 , 5, NULL, 11),
+(112 , 5, 1, 12),
+(113 , 5, NULL, 13),
+(114 , 5, NULL, 14),
+(115 , 5, NULL, 15),
+(116 , 6, 1, NULL),
+(117 , 6, 1, 10),
+(118 , 6, 1, 1),
+(119 , 6, 1, NULL),
+(120 , 6, 1, NULL),
+(121 , 6, 1, NULL),
+(122 , 6, 1, 2),
+(123 , 6, 1, 20),
+(124 , 6, 1, -10),
+(125 , 6, 1, NULL),
+(126 , 6, 1, NULL),
+(127 , 6, 1, NULL);
+select sum(b) over (partition by a order by b,pk
+rows between unbounded preceding and current row) as c1,
+avg(b) over (w1 rows between 1 preceding and 1 following) as c2,
+sum(c) over (w2 rows between 1 preceding and 1 following) as c5,
+avg(b) over (w1 rows between 5 preceding and 5 following) as c3,
+sum(b) over (w1 rows between 1 preceding and 1 following) as c4
+from t1
+window w1 as (partition by a order by b,pk),
+w2 as (partition by b order by c,pk);
+c1 c2 c5 c3 c4
+1 1.0000 42 1.0000 1
+1 1.0000 NULL 1.0000 2
+10 1.0000 NULL 1.0000 3
+10 10.0000 3 10.0000 20
+10 10.0000 9 10.0000 20
+10 15.0000 9 17.5000 30
+11 1.0000 NULL 1.0000 3
+12 1.0000 -10 1.0000 2
+2 1.0000 24 1.0000 3
+20 10.0000 12 10.0000 20
+20 10.0000 6 10.0000 20
+20 20.0000 27 20.0000 40
+3 1.0000 -7 1.0000 3
+30 16.6667 13 17.5000 50
+4 1.0000 NULL 1.0000 3
+40 20.0000 19 20.0000 40
+5 1.0000 NULL 1.0000 3
+50 20.0000 21 17.5000 60
+6 1.0000 NULL 1.0000 3
+7 1.0000 13 1.0000 3
+70 20.0000 24 17.5000 40
+8 1.0000 32 1.0000 3
+9 1.0000 -9 1.0000 3
+NULL 1.0000 29 1.0000 1
+NULL NULL 24 1.0000 NULL
+NULL NULL 38 1.0000 NULL
+NULL NULL 42 1.0000 NULL
+drop table t1;
+#
+# MDEV-9848: Window functions: reuse sorting and/or scanning
+#
+create table t1 (a int, b int, c int);
+insert into t1 values
+(1,3,1),
+(2,2,1),
+(3,1,1);
+# Check using counters
+flush status;
+select
+rank() over (partition by c order by a),
+rank() over (partition by c order by b)
+from t1;
+rank() over (partition by c order by a) rank() over (partition by c order by b)
+1 3
+2 2
+3 1
+show status like '%sort%';
+Variable_name Value
+Sort_merge_passes 0
+Sort_priority_queue_sorts 0
+Sort_range 0
+Sort_rows 6
+Sort_scan 2
+flush status;
+select
+rank() over (partition by c order by a),
+rank() over (partition by c order by a)
+from t1;
+rank() over (partition by c order by a) rank() over (partition by c order by a)
+1 1
+2 2
+3 3
+show status like '%sort%';
+Variable_name Value
+Sort_merge_passes 0
+Sort_priority_queue_sorts 0
+Sort_range 0
+Sort_rows 3
+Sort_scan 1
+explain format=json
+select
+rank() over (partition by c order by a),
+rank() over (partition by c order by a)
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.c, t1.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+explain format=json
+select
+rank() over (order by a),
+row_number() over (order by a)
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+explain format=json
+select
+rank() over (partition by c order by a),
+count(*) over (partition by c)
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.c, t1.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+explain format=json
+select
+count(*) over (partition by c),
+rank() over (partition by c order by a)
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.c, t1.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+drop table t1;
+#
+# MDEV-9847: Window functions: crash with big_tables=1
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set tmp_memory_table_size=0;
+select rank() over (order by a) from t1;
+rank() over (order by a)
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+set tmp_memory_table_size=default;
+drop table t1;
+#
+# Check if "ORDER BY window_func" works
+#
+create table t1 (s1 int, s2 char(5));
+insert into t1 values (1,'a');
+insert into t1 values (null,null);
+insert into t1 values (1,null);
+insert into t1 values (null,'a');
+insert into t1 values (2,'b');
+insert into t1 values (-1,'');
+explain format=json
+select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "filesort": {
+ "sort_key": "row_number() over ( order by t1.s1,t1.s2) desc",
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.s1, t1.s2"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 6,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+}
+select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
+s1 s2 X
+2 b 6
+1 a 5
+1 NULL 4
+-1 3
+NULL a 2
+NULL NULL 1
+drop table t1;
+#
+# Try window functions that are not directly present in the select list
+#
+create table t1 (a int, b int);
+insert into t1 values
+(1,3),
+(2,2),
+(3,1);
+select
+a, b,
+rank() over (order by a), rank() over (order by b),
+rank() over (order by a) - rank() over (order by b) as diff
+from
+t1;
+a b rank() over (order by a) rank() over (order by b) diff
+1 3 1 3 -2
+2 2 2 2 0
+3 1 3 1 2
+drop table t1;
+create table t1 (i int);
+insert into t1 values (1),(2);
+SELECT MAX(i) OVER (PARTITION BY (i)) FROM t1;
+MAX(i) OVER (PARTITION BY (i))
+1
+2
+drop table t1;
+#
+# Check the 0 in ROWS 0 PRECEDING
+#
+create table t1 (
+part_id int,
+pk int,
+a int
+);
+insert into t1 values (1, 1, 1);
+insert into t1 values (1, 2, 2);
+insert into t1 values (1, 3, 4);
+insert into t1 values (1, 4, 8);
+select
+pk, a,
+sum(a) over (order by pk rows between 0 preceding and current row)
+from t1;
+pk a sum(a) over (order by pk rows between 0 preceding and current row)
+1 1 1
+2 2 2
+3 4 4
+4 8 8
+select
+pk, a,
+sum(a) over (order by pk rows between 1 preceding and 0 preceding)
+from t1;
+pk a sum(a) over (order by pk rows between 1 preceding and 0 preceding)
+1 1 1
+2 2 3
+3 4 6
+4 8 12
+insert into t1 values (200, 1, 1);
+insert into t1 values (200, 2, 2);
+insert into t1 values (200, 3, 4);
+insert into t1 values (200, 4, 8);
+select
+part_id, pk, a,
+sum(a) over (partition by part_id order by pk rows between 0 preceding and current row)
+from t1;
+part_id pk a sum(a) over (partition by part_id order by pk rows between 0 preceding and current row)
+1 1 1 1
+1 2 2 2
+1 3 4 4
+1 4 8 8
+200 1 1 1
+200 2 2 2
+200 3 4 4
+200 4 8 8
+select
+part_id, pk, a,
+sum(a) over (partition by part_id order by pk rows between 1 preceding and 0 preceding)
+from t1;
+part_id pk a sum(a) over (partition by part_id order by pk rows between 1 preceding and 0 preceding)
+1 1 1 1
+1 2 2 3
+1 3 4 6
+1 4 8 12
+200 1 1 1
+200 2 2 3
+200 3 4 6
+200 4 8 12
+drop table t1;
+#
+# MDEV-9780, The "DISTINCT must not bet converted into GROUP BY when
+# window functions are present" part
+#
+create table t1 (part_id int, a int);
+insert into t1 values
+(100, 1),
+(100, 2),
+(100, 2),
+(100, 3),
+(2000, 1),
+(2000, 2),
+(2000, 3),
+(2000, 3),
+(2000, 3);
+select rank() over (partition by part_id order by a) from t1;
+rank() over (partition by part_id order by a)
+1
+2
+2
+4
+1
+2
+3
+3
+3
+select distinct rank() over (partition by part_id order by a) from t1;
+rank() over (partition by part_id order by a)
+1
+2
+4
+3
+explain format=json
+select distinct rank() over (partition by part_id order by a) from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "duplicate_removal": {
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.part_id, t1.a"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 9,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+}
+drop table t1;
+#
+# MDEV-9893: Window functions with different ORDER BY lists,
+# one of these lists containing an expression
+#
+create table t1 (s1 int, s2 char(5));
+insert into t1 values (1,'a');
+insert into t1 values (null,null);
+insert into t1 values (3,null);
+insert into t1 values (4,'a');
+insert into t1 values (2,'b');
+insert into t1 values (-1,'');
+select
+*,
+ROW_NUMBER() OVER (order by s1),
+CUME_DIST() OVER (order by -s1)
+from t1;
+s1 s2 ROW_NUMBER() OVER (order by s1) CUME_DIST() OVER (order by -s1)
+-1 2 1.0000000000
+1 a 3 0.8333333333
+2 b 4 0.6666666667
+3 NULL 5 0.5000000000
+4 a 6 0.3333333333
+NULL NULL 1 0.1666666667
+drop table t1;
+#
+# MDEV-9925: Wrong result with aggregate function as a window function
+#
+create table t1 (i int);
+insert into t1 values (1),(2);
+select i, sum(i) over (partition by i) from t1;
+i sum(i) over (partition by i)
+1 1
+2 2
+drop table t1;
+#
+# MDEV-9922: Assertion `!join->only_const_tables() && fsort' failed in int create_sort_index
+#
+create view v1 as select 1 as i;
+select rank() over (order by i) from v1;
+rank() over (order by i)
+1
+drop view v1;
+#
+# MDEV-10097: Assertion `count > 0' failed in Item_sum_sum::add_helper(bool)
+#
+CREATE TABLE `orders` (
+`o_orderkey` int(11) NOT NULL,
+`o_custkey` int(11) DEFAULT NULL,
+PRIMARY KEY (`o_orderkey`)
+) DEFAULT CHARSET=latin1;
+INSERT INTO `orders` VALUES (59908,242);
+INSERT INTO `orders` VALUES (59940,238);
+SELECT o_custkey, avg(o_custkey) OVER (PARTITION BY abs(o_custkey)
+ORDER BY o_custkey
+RANGE BETWEEN 15 FOLLOWING
+AND 15 FOLLOWING) from orders;
+o_custkey avg(o_custkey) OVER (PARTITION BY abs(o_custkey)
+ORDER BY o_custkey
+RANGE BETWEEN 15 FOLLOWING
+AND 15 FOLLOWING)
+238 NULL
+242 NULL
+DROP table orders;
+#
+# MDEV-10842: window functions with the same order column
+# but different directions
+#
+create table t1 (
+pk int primary key,
+a int,
+b int,
+c char(10)
+);
+insert into t1 values
+( 1, 0, 1, 'one'),
+( 2, 0, 2, 'two'),
+( 3, 0, 3, 'three'),
+( 4, 1, 1, 'one'),
+( 5, 1, 1, 'two'),
+( 6, 1, 2, 'three'),
+( 7, 2, NULL, 'n_one'),
+( 8, 2, 1, 'n_two'),
+( 9, 2, 2, 'n_three'),
+(10, 2, 0, 'n_four'),
+(11, 2, 10, NULL);
+select pk,
+row_number() over (order by pk desc) as r_desc,
+row_number() over (order by pk asc) as r_asc
+from t1;
+pk r_desc r_asc
+11 1 11
+10 2 10
+9 3 9
+8 4 8
+7 5 7
+6 6 6
+5 7 5
+4 8 4
+3 9 3
+2 10 2
+1 11 1
+drop table t1;
+#
+# MDEV-10874: two window functions with compatible sorting
+#
+create table t1 (
+pk int primary key,
+a int,
+b int,
+c char(10),
+d decimal(10, 3),
+e real
+);
+insert into t1 values
+( 1, 0, 1, 'one', 0.1, 0.001),
+( 2, 0, 2, 'two', 0.2, 0.002),
+( 3, 0, 3, 'three', 0.3, 0.003),
+( 4, 1, 2, 'three', 0.4, 0.004),
+( 5, 1, 1, 'two', 0.5, 0.005),
+( 6, 1, 1, 'one', 0.6, 0.006),
+( 7, 2, NULL, 'n_one', 0.5, 0.007),
+( 8, 2, 1, 'n_two', NULL, 0.008),
+( 9, 2, 2, NULL, 0.7, 0.009),
+(10, 2, 0, 'n_four', 0.8, 0.010),
+(11, 2, 10, NULL, 0.9, NULL);
+select pk, a, d,
+sum(d) over (partition by a order by pk
+ROWS between 1 preceding and current row) as sum_1,
+sum(d) over (order by a
+ROWS BETWEEN 1 preceding and 2 following) as sum_2
+from t1;
+pk a d sum_1 sum_2
+1 0 0.100 0.100 0.600
+2 0 0.200 0.300 1.000
+3 0 0.300 0.500 1.400
+4 1 0.400 0.400 1.800
+5 1 0.500 0.900 2.000
+6 1 0.600 1.100 1.600
+7 2 0.500 0.500 1.800
+8 2 NULL 0.500 2.000
+9 2 0.700 0.700 2.400
+10 2 0.800 1.500 2.400
+11 2 0.900 1.700 1.700
+explain format=json
+select pk, a, d,
+sum(d) over (partition by a order by pk
+ROWS between 1 preceding and current row) as sum_1,
+sum(d) over (order by a
+ROWS BETWEEN 1 preceding and 2 following) as sum_2
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.a, t1.pk"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 11,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+select pk, a, d,
+sum(d) over (partition by a order by pk desc
+ROWS between 1 preceding and current row) as sum_1,
+sum(d) over (order by a
+ROWS BETWEEN 1 preceding and 2 following) as sum_2
+from t1;
+pk a d sum_1 sum_2
+3 0 0.300 0.300 0.600
+2 0 0.200 0.500 1.200
+1 0 0.100 0.300 1.400
+6 1 0.600 0.600 1.600
+5 1 0.500 1.100 2.400
+4 1 0.400 0.900 2.600
+11 2 0.900 0.900 2.800
+10 2 0.800 1.700 2.400
+9 2 0.700 1.500 2.000
+8 2 NULL 0.700 1.200
+7 2 0.500 0.500 0.500
+drop table t1;
+#
+# MDEV-9941: two window functions with compatible partitions
+#
+create table t1 (
+a int,
+b int,
+c int
+);
+insert into t1 values
+(10, 1, 1),
+(10, 3, 10),
+(10, 1, 10),
+(10, 3, 100),
+(10, 5, 1000),
+(10, 1, 100);
+explain format=json
+select
+a,b,c,
+row_number() over (partition by a),
+row_number() over (partition by a, b)
+from t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "t1.a, t1.b"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 6,
+ "filtered": 100
+ }
+ }
+ }
+ }
+}
+drop table t1;
+#
+# MDEV-10815: Window Function Expressions Wrong Results
+#
+create table t(a decimal(35,10), b int);
+insert into t(a,b) values(1,1);
+insert into t(a,b) values(2,1);
+insert into t(a,b) values(0,1);
+insert into t(a,b) values(1, 2);
+insert into t(a,b) values(1.5,2);
+insert into t(a,b) values(3, 2);
+insert into t(a,b) values(4.5,2);
+select a, b,
+sum(t.a) over (partition by t.b order by a) as simple_sum,
+sum(t.a) over (partition by t.b order by a) + 1 as sum_and_const,
+sum(t.b) over (partition by t.b order by a) + sum(t.a) over (partition by t.b order by a) as sum_and_sum
+from t
+order by t.b, t.a;
+a b simple_sum sum_and_const sum_and_sum
+0.0000000000 1 0.0000000000 1.0000000000 1.0000000000
+1.0000000000 1 1.0000000000 2.0000000000 3.0000000000
+2.0000000000 1 3.0000000000 4.0000000000 6.0000000000
+1.0000000000 2 1.0000000000 2.0000000000 3.0000000000
+1.5000000000 2 2.5000000000 3.5000000000 6.5000000000
+3.0000000000 2 5.5000000000 6.5000000000 11.5000000000
+4.5000000000 2 10.0000000000 11.0000000000 18.0000000000
+drop table t;
+#
+# MDEV-10669: Crash in SELECT with window function used
+#
+create table t(a decimal(35,10), b int);
+insert into t(a,b) values(1,1);
+insert into t(a,b) values(2,1);
+insert into t(a,b) values(0,1);
+SELECT (CASE WHEN sum(t.a) over (partition by t.b)=0 THEN null ELSE null END) AS a FROM t;
+a
+NULL
+NULL
+NULL
+SELECT ifnull(((t.a) / CASE WHEN sum(t.a) over(partition by t.b) =0 then null else null end) ,0) from t;
+ifnull(((t.a) / CASE WHEN sum(t.a) over(partition by t.b) =0 then null else null end) ,0)
+0.00000000000000
+0.00000000000000
+0.00000000000000
+SELECT sum(t.a) over (partition by t.b order by a),
+sqrt(ifnull((sum(t.a) over (partition by t.b order by a)), 0))
+from t;
+sum(t.a) over (partition by t.b order by a) sqrt(ifnull((sum(t.a) over (partition by t.b order by a)), 0))
+0.0000000000 0
+1.0000000000 1
+3.0000000000 1.7320508075688772
+drop table t;
+#
+# MDEV-10868: view definitions with window functions
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+pk c
+1 1
+2 1
+3 1
+4 1
+5 2
+6 2
+7 2
+8 2
+9 2
+10 2
+select pk, c, c/count(*) over (partition by c order by pk
+rows between 1 preceding and 2 following) as CNT
+from t1;
+pk c CNT
+1 1 0.3333
+2 1 0.2500
+3 1 0.3333
+4 1 0.5000
+5 2 0.6667
+6 2 0.5000
+7 2 0.5000
+8 2 0.5000
+9 2 0.6667
+10 2 1.0000
+create view v1 as select pk, c, c/count(*) over (partition by c order by pk
+rows between 1 preceding and 2 following) as CNT
+from t1;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between 1 preceding and 2 following ) AS `CNT` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+pk c CNT
+1 1 0.3333
+2 1 0.2500
+3 1 0.3333
+4 1 0.5000
+5 2 0.6667
+6 2 0.5000
+7 2 0.5000
+8 2 0.5000
+9 2 0.6667
+10 2 1.0000
+select pk, c, c/count(*) over w1 as CNT from t1
+window w1 as (partition by c order by pk rows between 1 preceding and 2 following);
+pk c CNT
+1 1 0.3333
+2 1 0.2500
+3 1 0.3333
+4 1 0.5000
+5 2 0.6667
+6 2 0.5000
+7 2 0.5000
+8 2 0.5000
+9 2 0.6667
+10 2 1.0000
+create view v2 as select pk, c, c/count(*) over w1 as CNT from t1
+window w1 as (partition by c order by pk rows between 1 preceding and 2 following);
+show create view v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between 1 preceding and 2 following ) AS `CNT` from `t1` latin1 latin1_swedish_ci
+select * from v2;
+pk c CNT
+1 1 0.3333
+2 1 0.2500
+3 1 0.3333
+4 1 0.5000
+5 2 0.6667
+6 2 0.5000
+7 2 0.5000
+8 2 0.5000
+9 2 0.6667
+10 2 1.0000
+select pk, c, c/count(*) over w1 as CNT from t1
+window w1 as (partition by c order by pk rows unbounded preceding);
+pk c CNT
+1 1 1.0000
+2 1 0.5000
+3 1 0.3333
+4 1 0.2500
+5 2 2.0000
+6 2 1.0000
+7 2 0.6667
+8 2 0.5000
+9 2 0.4000
+10 2 0.3333
+create view v3 as select pk, c, c/count(*) over w1 as CNT from t1
+window w1 as (partition by c order by pk rows unbounded preceding);
+show create view v3;
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between unbounded preceding and current row ) AS `CNT` from `t1` latin1 latin1_swedish_ci
+select * from v3;
+pk c CNT
+1 1 1.0000
+2 1 0.5000
+3 1 0.3333
+4 1 0.2500
+5 2 2.0000
+6 2 1.0000
+7 2 0.6667
+8 2 0.5000
+9 2 0.4000
+10 2 0.3333
+select pk, c, c/count(*) over (partition by c order by pk
+range between 3 preceding and current row) as CNT
+from t1;
+pk c CNT
+1 1 1.0000
+2 1 0.5000
+3 1 0.3333
+4 1 0.2500
+5 2 2.0000
+6 2 1.0000
+7 2 0.6667
+8 2 0.5000
+9 2 0.5000
+10 2 0.5000
+create view v4 as select pk, c, c/count(*) over (partition by c order by pk
+range between 3 preceding and current row) as CNT
+from t1;
+show create view v4;
+View Create View character_set_client collation_connection
+v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` range between 3 preceding and current row ) AS `CNT` from `t1` latin1 latin1_swedish_ci
+select * from v4;
+pk c CNT
+1 1 1.0000
+2 1 0.5000
+3 1 0.3333
+4 1 0.2500
+5 2 2.0000
+6 2 1.0000
+7 2 0.6667
+8 2 0.5000
+9 2 0.5000
+10 2 0.5000
+drop view v1,v2,v3,v4;
+drop table t0,t1;
+#
+# MDEV-10875: window function in subquery
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (3),(1);
+CREATE TABLE t2 (c VARCHAR(8));
+INSERT INTO t2 VALUES ('foo'),('bar'),('foo');
+SELECT COUNT(*) OVER (PARTITION BY c) FROM t2;
+COUNT(*) OVER (PARTITION BY c)
+1
+2
+2
+SELECT * FROM t1 WHERE i IN ( SELECT COUNT(*) OVER (PARTITION BY c) FROM t2 );
+i
+1
+DROP TABLE t1, t2;
+#
+# MDEV-9976: window function without PARTITION BY and ORDER BY
+#
+CREATE TABLE t1 (id int, a int);
+INSERT INTO t1 VALUES
+(1,1000), (2,1100), (3,1800), (4,1500), (5,1700), (6,1200),
+(7,2000), (8,2100), (9,1600);
+SELECT id, sum(a) OVER (PARTITION BY id
+ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+FROM t1;
+id sum(a) OVER (PARTITION BY id
+1 1000
+2 1100
+3 1800
+4 1500
+5 1700
+6 1200
+7 2000
+8 2100
+9 1600
+ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+SELECT id, sum(a) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+FROM t1;
+id sum(a) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+1 14000
+2 13000
+3 5900
+4 10700
+5 7600
+6 11900
+7 4100
+8 2100
+9 9200
+DROP TABLE t1;
+#
+# MDEV-11867: window function with aggregation
+# over the result of grouping
+#
+create table t1 (
+username varchar(32),
+amount int
+);
+insert into t1 values
+('user1',1),
+('user1',5),
+('user1',3),
+('user2',10),
+('user2',20),
+('user2',30);
+select username, sum(amount) as s, avg(sum(amount)) over (order by s desc)
+from t1
+group by username;
+username s avg(sum(amount)) over (order by s desc)
+user1 9 34.5000
+user2 60 60.0000
+select username, sum(amount), avg(sum(amount)) over (order by sum(amount) desc)
+from t1
+group by username;
+username sum(amount) avg(sum(amount)) over (order by sum(amount) desc)
+user1 9 34.5000
+user2 60 60.0000
+drop table t1;
+#
+# MDEV-11594: window function over implicit grouping
+#
+create table t1 (id int);
+insert into t1 values (1), (2), (3), (2);
+select sum(id) over (order by sum(id)) from t1;
+sum(id) over (order by sum(id))
+1
+select sum(sum(id)) over (order by sum(id)) from t1;
+sum(sum(id)) over (order by sum(id))
+8
+drop table t1;
+#
+# MDEV-9923: integer constant in order by list
+# of window specification
+#
+create table t1 (id int);
+insert into t1 values (1), (2), (3), (2);
+select rank() over (order by 1) from t1;
+rank() over (order by 1)
+1
+1
+1
+1
+select rank() over (order by 2) from t1;
+rank() over (order by 2)
+1
+1
+1
+1
+select rank() over (partition by id order by 2) from t1;
+rank() over (partition by id order by 2)
+1
+1
+1
+1
+drop table t1;
+#
+# MDEV-10660: view using a simple window function
+#
+create table t1 (id int);
+insert into t1 values (1), (2), (3), (2);
+create view v1(id,rnk) as
+select id, rank() over (order by id) from t1;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,rank() over ( order by `t1`.`id`) AS `rnk` from `t1` latin1 latin1_swedish_ci
+select id, rank() over (order by id) from t1;
+id rank() over (order by id)
+1 1
+2 2
+2 2
+3 4
+select * from v1;
+id rnk
+1 1
+2 2
+2 2
+3 4
+drop view v1;
+drop table t1;
+#
+# MDEV-11138: window function in the query without tables
+#
+select row_number() over ();
+row_number() over ()
+1
+select count(*) over ();
+count(*) over ()
+1
+select sum(5) over ();
+sum(5) over ()
+5
+select row_number() over (), sum(5) over ();
+row_number() over () sum(5) over ()
+1 5
+select row_number() over (order by 2);
+row_number() over (order by 2)
+1
+select row_number() over (partition by 2);
+row_number() over (partition by 2)
+1
+select row_number() over (partition by 4 order by 1+2);
+row_number() over (partition by 4 order by 1+2)
+1
+#
+# MDEV-11999: execution of prepared statement for
+# tableless query with window functions
+#
+prepare stmt from
+"select row_number() over (partition by 4 order by 1+2)";
+execute stmt;
+row_number() over (partition by 4 order by 1+2)
+1
+execute stmt;
+row_number() over (partition by 4 order by 1+2)
+1
+deallocate prepare stmt;
+#
+# MDEV-11745: window function with min/max
+#
+create table t1 (i int, b int);
+insert into t1 values
+(1,1),(2,1),(3,1),(4,4),(5,4),(6,4),(7,8),(8,8),(9,8),(10,8);
+select b, min(i) over (partition by b) as f
+from t1 as tt
+order by i;
+b f
+1 1
+1 1
+1 1
+4 4
+4 4
+4 4
+8 7
+8 7
+8 7
+8 7
+select b, min(i) over (partition by b) as f
+from (select * from t1) as tt
+order by i;
+b f
+1 1
+1 1
+1 1
+4 4
+4 4
+4 4
+8 7
+8 7
+8 7
+8 7
+select b, min(i+10) over (partition by b) as f
+from t1 as tt
+order by i;
+b f
+1 11
+1 11
+1 11
+4 14
+4 14
+4 14
+8 17
+8 17
+8 17
+8 17
+select b, min(i) over (partition by b) as f
+from (select i+10 as i, b from t1) as tt
+order by i;
+b f
+1 11
+1 11
+1 11
+4 14
+4 14
+4 14
+8 17
+8 17
+8 17
+8 17
+select b, min(i+20) over (partition by b) as f
+from (select i+10 as i, b from t1) as tt
+order by i;
+b f
+1 31
+1 31
+1 31
+4 34
+4 34
+4 34
+8 37
+8 37
+8 37
+8 37
+select b, max(i) over (partition by b) as f
+from t1 as tt
+order by i;
+b f
+1 3
+1 3
+1 3
+4 6
+4 6
+4 6
+8 10
+8 10
+8 10
+8 10
+select b, max(i) over (partition by b) as f
+from (select * from t1) as tt
+order by i;
+b f
+1 3
+1 3
+1 3
+4 6
+4 6
+4 6
+8 10
+8 10
+8 10
+8 10
+select b, max(i+10) over (partition by b) as f
+from t1 as tt
+order by i;
+b f
+1 13
+1 13
+1 13
+4 16
+4 16
+4 16
+8 20
+8 20
+8 20
+8 20
+select b, max(i) over (partition by b) as f
+from (select i+10 as i, b from t1) as tt
+order by i;
+b f
+1 13
+1 13
+1 13
+4 16
+4 16
+4 16
+8 20
+8 20
+8 20
+8 20
+select b, max(i+20) over (partition by b) as f
+from (select i+10 as i, b from t1) as tt
+order by i;
+b f
+1 33
+1 33
+1 33
+4 36
+4 36
+4 36
+8 40
+8 40
+8 40
+8 40
+select max(i), max(i), sum(i), count(i)
+from t1 as tt
+group by b;
+max(i) max(i) sum(i) count(i)
+3 3 6 3
+6 6 15 3
+10 10 34 4
+select max(i), min(sum(i)) over (partition by count(i)) f
+from t1 as tt
+group by b;
+max(i) f
+3 6
+6 6
+10 34
+select max(i), min(sum(i)) over (partition by count(i)) f
+from (select * from t1) as tt
+group by b;
+max(i) f
+3 6
+6 6
+10 34
+select max(i+10), min(sum(i)+10) over (partition by count(i)) f
+from t1 as tt
+group by b;
+max(i+10) f
+13 16
+16 16
+20 44
+select max(i), max(i), sum(i), count(i)
+from (select i+10 as i, b from t1) as tt
+group by b;
+max(i) max(i) sum(i) count(i)
+13 13 36 3
+16 16 45 3
+20 20 74 4
+select max(i), min(sum(i)) over (partition by count(i)) f
+from (select i+10 as i, b from t1) as tt
+group by b;
+max(i) f
+13 36
+16 36
+20 74
+select max(i), min(i), min(max(i)-min(i)) over (partition by count(i)) f
+from (select i+10 as i, b from t1) as tt
+group by b;
+max(i) min(i) f
+13 11 2
+16 14 2
+20 17 3
+drop table t1;
+#
+# MDEV-12015: window function over select with WHERE
+# that is always FALSE
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT i, ROW_NUMBER() OVER () FROM t1 WHERE 1 = 2;
+i ROW_NUMBER() OVER ()
+SELECT i, COUNT(*) OVER () FROM t1 WHERE 1 = 2;
+i COUNT(*) OVER ()
+DROP TABLE t1;
+#
+# MDEV-12051: window function in query with implicit grouping
+# on always empty set
+#
+create table t1 (a int, b varchar(8));
+insert into t1 values (1,'foo'),(2,'bar');
+select max(a), row_number() over () from t1 where a > 10;
+max(a) row_number() over ()
+NULL 1
+select max(a), sum(max(a)) over () from t1 where a > 10;
+max(a) sum(max(a)) over ()
+NULL NULL
+select max(a), sum(max(a)) over (partition by max(a)) from t1 where a > 10;
+max(a) sum(max(a)) over (partition by max(a))
+NULL NULL
+select max(a), row_number() over () from t1 where 1 = 2;
+max(a) row_number() over ()
+NULL 1
+select max(a), sum(max(a)) over () from t1 where 1 = 2;
+max(a) sum(max(a)) over ()
+NULL NULL
+select max(a), sum(max(a)) over (partition by max(a)) from t1 where 1 = 2;
+max(a) sum(max(a)) over (partition by max(a))
+NULL NULL
+select max(a), row_number() over () from t1 where 1 = 2
+having max(a) is not null;
+max(a) row_number() over ()
+select max(a), sum(max(a)) over () from t1 where 1 = 2
+having max(a) is not null;
+max(a) sum(max(a)) over ()
+drop table t1;
+#
+# MDEV-10885: window function in query with implicit grouping
+# with constant condition evaluated to false
+#
+CREATE TABLE t1 (a INT, b VARCHAR(8));
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+CREATE TABLE t2 (c INT);
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (d INT);
+INSERT INTO t3 VALUES (5),(6);
+SELECT MAX(a), ROW_NUMBER() OVER (PARTITION BY MAX(a)) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+MAX(a) ROW_NUMBER() OVER (PARTITION BY MAX(a))
+NULL 1
+SELECT MAX(a), COUNT(MAX(a)) OVER (PARTITION BY MAX(a)) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+MAX(a) COUNT(MAX(a)) OVER (PARTITION BY MAX(a))
+NULL 0
+SELECT MAX(a), SUM(MAX(a)) OVER (PARTITION BY MAX(a)) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+MAX(a) SUM(MAX(a)) OVER (PARTITION BY MAX(a))
+NULL NULL
+SELECT MAX(a), ROW_NUMBER() OVER (PARTITION BY MAX(a)) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) )
+HAVING MAX(a) IS NOT NULL;
+MAX(a) ROW_NUMBER() OVER (PARTITION BY MAX(a))
+SELECT a, MAX(a), ROW_NUMBER() OVER (PARTITION BY b) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+a MAX(a) ROW_NUMBER() OVER (PARTITION BY b)
+NULL NULL 1
+SELECT a, COUNT(a), AVG(a) OVER (PARTITION BY b) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+a COUNT(a) AVG(a) OVER (PARTITION BY b)
+NULL 0 NULL
+SELECT a, MAX(a), AVG(a) OVER (PARTITION BY b) FROM t1
+WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) );
+a MAX(a) AVG(a) OVER (PARTITION BY b)
+NULL NULL NULL
+DROP TABLE t1,t2,t3;
+#
+# MDEV-10859: Wrong result of aggregate window function in query
+# with HAVING and no ORDER BY
+#
+create table empsalary (depname varchar(32), empno smallint primary key, salary int);
+insert into empsalary values
+('develop', 1, 5000), ('develop', 2, 4000),('sales', 3, '6000'),('sales', 4, 5000);
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
+depname empno salary avg(salary) OVER (PARTITION BY depname)
+develop 1 5000 4500.0000
+develop 2 4000 4500.0000
+sales 3 6000 5500.0000
+sales 4 5000 5500.0000
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname;
+depname empno salary avg(salary) OVER (PARTITION BY depname)
+develop 1 5000 4500.0000
+develop 2 4000 4500.0000
+sales 3 6000 5500.0000
+sales 4 5000 5500.0000
+#
+# These last 2 should have the same row results, ignoring order.
+#
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary HAVING empno > 1;
+depname empno salary avg(salary) OVER (PARTITION BY depname)
+develop 2 4000 4000.0000
+sales 3 6000 5500.0000
+sales 4 5000 5500.0000
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary HAVING empno > 1 ORDER BY depname;
+depname empno salary avg(salary) OVER (PARTITION BY depname)
+develop 2 4000 4000.0000
+sales 3 6000 5500.0000
+sales 4 5000 5500.0000
+drop table empsalary;
+#
+# MDEV-11868: min(distinct) over () returns wrong value
+#
+create table TDEC (CDEC int, RNUM int);
+create view VDEC as select * from TDEC;
+insert into TDEC (CDEC) values (null),(-1),(0),(1),(0),(10);
+select TDEC.CDEC, min(TDEC.CDEC) over () from TDEC;
+CDEC min(TDEC.CDEC) over ()
+NULL -1
+-1 -1
+0 -1
+0 -1
+1 -1
+10 -1
+select VDEC.CDEC, min(VDEC.CDEC) over () from VDEC;
+CDEC min(VDEC.CDEC) over ()
+NULL -1
+-1 -1
+0 -1
+0 -1
+1 -1
+10 -1
+select TDEC.CDEC, max(TDEC.CDEC) over () from TDEC;
+CDEC max(TDEC.CDEC) over ()
+NULL 10
+-1 10
+0 10
+0 10
+1 10
+10 10
+select VDEC.CDEC, max(VDEC.CDEC) over () from VDEC;
+CDEC max(VDEC.CDEC) over ()
+NULL 10
+-1 10
+0 10
+0 10
+1 10
+10 10
+select TDEC.CDEC, min(distinct TDEC.CDEC) over () from TDEC;
+CDEC min(distinct TDEC.CDEC) over ()
+NULL -1
+-1 -1
+0 -1
+0 -1
+1 -1
+10 -1
+select VDEC.CDEC, min(distinct VDEC.CDEC) over () from VDEC;
+CDEC min(distinct VDEC.CDEC) over ()
+NULL -1
+-1 -1
+0 -1
+0 -1
+1 -1
+10 -1
+select TDEC.CDEC, max(distinct TDEC.CDEC) over () from TDEC;
+CDEC max(distinct TDEC.CDEC) over ()
+NULL 10
+-1 10
+0 10
+0 10
+1 10
+10 10
+select VDEC.CDEC, max(distinct VDEC.CDEC) over () from VDEC;
+CDEC max(distinct VDEC.CDEC) over ()
+NULL 10
+-1 10
+0 10
+0 10
+1 10
+10 10
+#
+# These should be removed once support for them is added.
+#
+select TDEC.CDEC, count(distinct TDEC.CDEC) over () from TDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'COUNT(DISTINCT) aggregate as window function'
+select VDEC.CDEC, count(distinct VDEC.CDEC) over () from VDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'COUNT(DISTINCT) aggregate as window function'
+select TDEC.CDEC, sum(distinct TDEC.CDEC) over () from TDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'SUM(DISTINCT) aggregate as window function'
+select VDEC.CDEC, sum(distinct VDEC.CDEC) over () from VDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'SUM(DISTINCT) aggregate as window function'
+select TDEC.CDEC, avg(distinct TDEC.CDEC) over () from TDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'AVG(DISTINCT) aggregate as window function'
+select VDEC.CDEC, avg(distinct VDEC.CDEC) over () from VDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'AVG(DISTINCT) aggregate as window function'
+select TDEC.CDEC, GROUP_CONCAT(TDEC.CDEC) over () from TDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'GROUP_CONCAT() aggregate as window function'
+select VDEC.CDEC, GROUP_CONCAT(distinct VDEC.CDEC) over () from VDEC;
+ERROR 42000: This version of MariaDB doesn't yet support 'GROUP_CONCAT() aggregate as window function'
+drop table TDEC;
+drop view VDEC;
+#
+# MDEV-10700: 10.2.2 windowing function returns incorrect result
+#
+create table t(a int,b int, c int , d int);
+insert into t(a,b,c,d) values(1, rand(10)*1000, rand(10)*1000, rand(10)*1000);
+insert into t(a,b,c,d) values(1, rand(10)*1000, rand(10)*1000, rand(10)*1000);
+replace into t(a,b,c,d) select 1, rand(10)*1000, rand(10)*1000, rand(10)*1000 from t t1, t t2, t t3, t t4, t t5, t t6, t t7, t t8, t t9, t t10, t t11, t t12, t t13, t t14, t t15, t t16, t t17;
+select count(distinct s) from (select sum(d) over(partition by a,b,c) as s from t) Z where s > 0;
+count(distinct s)
+993
+select count(distinct s) from (select sum(d) as s from t group by a,b,c) Z where s > 0;
+count(distinct s)
+993
+select count(distinct s) from (select sum(d) over(partition by a,b) as s from t) Z where s > 0;
+count(distinct s)
+993
+select count(distinct s) from (select sum(d) as s from t group by a,b) Z where s > 0;
+count(distinct s)
+993
+select count(distinct s) from (select sum(d) over(partition by a) as s from t) Z where s > 0;
+count(distinct s)
+1
+select count(distinct s) from (select sum(d) as s from t group by a) Z where s > 0;
+count(distinct s)
+1
+drop table t;
+#
+# MDEV-9924: window function in query with group by optimized away
+#
+create table t1 (i int);
+insert into t1 values (2),(3),(1);
+select row_number() over () from t1 group by 1+2;
+row_number() over ()
+1
+select max(i), row_number() over () from t1 group by 1+2;
+max(i) row_number() over ()
+3 1
+select rank() over (order by max(i)) from t1 group by 1+2;
+rank() over (order by max(i))
+1
+select i, row_number() over () from t1 group by 1+2;
+i row_number() over ()
+2 1
+select i, rank() over (order by i) rnk from t1 group by 1+2;
+i rnk
+2 1
+drop table t1;
+#
+# MDEV-11907: window function as the second operand of division
+#
+create table t1 (pk int, c int);
+insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2);
+set @sql_mode_save= @@sql_mode;
+set sql_mode='ERROR_FOR_DIVISION_BY_ZERO';
+select pk, c, c/count(*) over
+(partition by c order by pk
+rows between 1 preceding and 2 following) as CNT
+from t1;
+pk c CNT
+1 1 0.3333
+2 1 0.2500
+3 1 0.3333
+4 1 0.5000
+5 2 2.0000
+show warnings;
+Level Code Message
+set sql_mode=@sql_mode_save;
+drop table t1;
+#
+# MDEV-12336: several functions over a window function
+#
+create table t1 (name varchar(10), cnt int);
+insert into t1 values ('Fred', 23), ('Fred', 35), ('Joe', 10);
+select q.name, q.row_cnt,
+round( 100 * ( q.row_cnt /
+sum(q.row_cnt) over
+(
+order by q.name
+rows between
+unbounded preceding and
+unbounded following
+)
+),2
+) pct_of_total
+from
+(
+select name, count(*) row_cnt, sum(cnt) sum_cnt
+from t1
+group by 1
+) q;
+name row_cnt pct_of_total
+Fred 2 66.67
+Joe 1 33.33
+drop table t1;
+#
+# MDEV-11990: window function over min/max aggregation
+#
+create table t1 (id int);
+insert into t1 values (1), (2), (3), (2), (4), (2);
+select sum(max(id)) over (order by max(id)) from t1;
+sum(max(id)) over (order by max(id))
+4
+explain
+select sum(max(id)) over (order by max(id)) from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary
+create index idx on t1(id);
+select sum(max(id)) over (order by max(id)) from t1;
+sum(max(id)) over (order by max(id))
+4
+explain
+select sum(max(id)) over (order by max(id)) from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
+select sum(max(id)) over (order by max(id)) from t1 where id < 3;
+sum(max(id)) over (order by max(id))
+2
+select count(max(id)) over (order by max(id)) from t1 where id < 3;
+count(max(id)) over (order by max(id))
+1
+select max(id), rank() over (order by max(id)) from t1 where id < 3;
+max(id) rank() over (order by max(id))
+2 1
+drop table t1;
+#
+# main.win failure post MDEV-12336
+#
+create table t(a decimal(35,10), b int);
+insert into t values (1, 10), (2, 20), (3, 30);
+prepare stmt from "SELECT (CASE WHEN sum(t.a) over (partition by t.b)=1 THEN 1000 ELSE 300 END) AS a FROM t";
+execute stmt;
+a
+1000
+300
+300
+drop table t;
+#
+# MDEV-12851 case with window functions query crashes server
+#
+create table t1(dt datetime);
+insert into t1 values ('2017-05-17'), ('2017-05-18');
+select dt,
+case when (max(dt) over (order by dt rows between 1 following and 1 following) is null)
+then '9999-12-31 12:00:00'
+ else max(dt) over (order by dt rows between 1 following and 1 following)
+end x,
+case when (max(dt) over (order by dt rows between 1 following and 1 following) is not null)
+then '9999-12-31 12:00:00'
+ else max(dt) over (order by dt rows between 1 following and 1 following)
+end x
+from t1;
+dt x x
+2017-05-17 00:00:00 2017-05-18 00:00:00 9999-12-31 12:00:00
+2017-05-18 00:00:00 9999-12-31 12:00:00 NULL
+drop table t1;
+create table t1(i int);
+insert into t1 values (null),(1),(2);
+select max(i) over (order by i),
+max(i) over (order by i) is null,
+max(i) over (order by i) is not null
+from t1;
+max(i) over (order by i) max(i) over (order by i) is null max(i) over (order by i) is not null
+NULL 1 0
+1 0 1
+2 0 1
+drop table t1;
+#
+# MDEV-13189: Window functions crash when using INTERVAL function
+#
+create table t1(i int);
+insert into t1 values (1),(2),(10),(20),(30);
+select sum(i) over (order by i), interval(sum(i) over (order by i), 10, 20)
+from t1;
+sum(i) over (order by i) interval(sum(i) over (order by i), 10, 20)
+1 0
+3 0
+13 1
+33 2
+63 2
+drop table t1;
+#
+# MDEV-13352: Server crashes in st_join_table::remove_duplicates
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+ROW_NUMBER() OVER() i
+SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+ROW_NUMBER() OVER() i
+DROP TABLE t1;
+#
+# MDEV-13344: Server crashes in in AGGR_OP::put_record on subquery
+# with window function and constant table
+# (Testcase only)
+#
+CREATE TABLE t1 (c CHAR(8)) ENGINE=MyISAM;
+INSERT IGNORE INTO t1 VALUES ('foo');
+SELECT ('bar',1) IN ( SELECT c, ROW_NUMBER() OVER (PARTITION BY c) FROM t1);
+('bar',1) IN ( SELECT c, ROW_NUMBER() OVER (PARTITION BY c) FROM t1)
+0
+DROP TABLE t1;
+#
+# MDEV-13351: Server crashes in st_select_lex::set_explain_type upon UNION with window function
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT Nth_value(i,1) OVER() FROM t1
+UNION ALL
+( SELECT Nth_value(i,2) OVER() FROM t1 LIMIT 0 )
+;
+Nth_value(i,1) OVER()
+1
+1
+DROP TABLE t1;
+#
+# A regression after MDEV-13351:
+# MDEV-13374 : Server crashes in first_linear_tab / st_select_lex::set_explain_type
+# upon UNION with aggregate function
+#
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+SELECT i AS fld FROM t1 UNION SELECT COUNT(*) AS fld FROM t1;
+fld
+1
+2
+DROP TABLE t1;
+#
+# MDEV-13240 Wrong warning with MAX(datetime_field) OVER (...)
+#
+CREATE TABLE t1 (dt DATETIME);
+INSERT INTO t1 VALUES ('2017-05-17');
+SELECT MAX(dt) OVER (ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) FROM t1;
+MAX(dt) OVER (ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
+NULL
+DROP TABLE t1;
+#
+# MDEV-13358 FIRST_VALUE throws SQL Error (1292): Incorrect datetime value
+#
+CREATE TABLE IF NOT EXISTS `fv_test` (
+`SOME_DATE` datetime NOT NULL
+);
+INSERT INTO `fv_test` (`SOME_DATE`) VALUES ('2017-07-20 12:47:56');
+CREATE TABLE fv_result
+SELECT
+FIRST_VALUE(SOME_DATE) OVER(ORDER BY SOME_DATE DESC) AS somedate
+FROM fv_test;
+SHOW CREATE TABLE fv_result;
+Table Create Table
+fv_result CREATE TABLE `fv_result` (
+ `somedate` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM fv_result;
+somedate
+2017-07-20 12:47:56
+DROP TABLE fv_test, fv_result;
+#
+# MDEV-13649: Server crashes in set_field_to_null_with_conversions or in Field::set_notnull
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0),(1),(2);
+SELECT LEAD(a) OVER (PARTITION BY a ORDER BY a) as lead,
+a AND LEAD(a) OVER (PARTITION BY a ORDER BY a) AS a_and_lead_part
+FROM t1;
+lead a_and_lead_part
+NULL 0
+NULL NULL
+NULL NULL
+SELECT a OR LEAD(a) OVER (ORDER BY a) AS a_or_lead_order
+FROM t1
+ORDER BY a;
+a_or_lead_order
+1
+1
+1
+SELECT a AND LEAD(a) OVER (ORDER BY a) AS a_and_lead_order
+FROM t1
+ORDER BY a;
+a_and_lead_order
+0
+1
+NULL
+SELECT a XOR LEAD(a) OVER (ORDER BY a) AS a_xor_lead_order
+FROM t1
+ORDER BY a;
+a_xor_lead_order
+1
+0
+NULL
+SELECT NOT LEAD(a) OVER (ORDER BY a) AS not_lead_order
+FROM t1
+ORDER BY a;
+not_lead_order
+0
+0
+NULL
+SELECT LEAD(a) OVER (ORDER BY a) is not null AS is_not_null_lead_order
+FROM t1
+ORDER BY a;
+is_not_null_lead_order
+1
+1
+0
+drop table t1;
+#
+# MDEV-13354: Server crashes in find_field_in_tables upon PS with window function and subquery
+#
+CREATE TABLE t1 (i INT, a char);
+INSERT INTO t1 VALUES (1, 'a'),(2, 'b');
+PREPARE stmt FROM "SELECT row_number() over (partition by i order by i), i FROM (SELECT * from t1) as sq";
+EXECUTE stmt;
+row_number() over (partition by i order by i) i
+1 1
+1 2
+DROP TABLE t1;
+#
+# MDEV-13384: "window" seems like a reserved column name but it's not listed as one
+#
+# Currently we allow window as an identifier, except for table aliases.
+#
+CREATE TABLE door (id INT, window VARCHAR(10));
+SELECT id
+FROM door as window;
+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 'window' at line 2
+SELECT id, window
+FROM door;
+id window
+SELECT id, window
+FROM door as window;
+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 'window' at line 2
+DROP TABLE door;
+#
+# MDEV-13352: Server crashes in st_join_table::remove_duplicates
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+ROW_NUMBER() OVER() i
+SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0;
+ROW_NUMBER() OVER() i
+DROP TABLE t1;
+#
+# MDEV-15853: Assertion `tab->filesort_result == 0' failed
+#
+CREATE TABLE t1 ( a1 int);
+insert into t1 values (1),(2),(3);
+CREATE TABLE t2 (b1 int, a1 int, a2 int);
+insert into t2 values (1,2,3),(2,3,4),(3,4,5);
+SELECT COUNT(DISTINCT t2.a2),
+rank() OVER (ORDER BY t2.b1)
+FROM t2 ,t1 GROUP BY t2.b1 ORDER BY t1.a1;
+COUNT(DISTINCT t2.a2) rank() OVER (ORDER BY t2.b1)
+1 1
+1 2
+1 3
+DROP TABLE t1,t2;
+#
+# MDEV-16990: server crashes in base_list_iterator::next
+#
+CREATE TABLE t1(i int);
+insert into t1 values (1),(2);
+SELECT DISTINCT row_number() OVER (), MAX(1) FROM t1;
+row_number() OVER () MAX(1)
+1 1
+SELECT DISTINCT BIT_AND(0) OVER (), MAX(1) FROM t1;
+BIT_AND(0) OVER () MAX(1)
+0 1
+drop table t1;
+#
+# MDEV-17525: Window functions not working in ONLY_FULL_GROUP_BY mode
+#
+CREATE TABLE t1 (name CHAR(10), test CHAR(10), score TINYINT);
+INSERT INTO t1 VALUES
+('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
+('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
+('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
+('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);
+SET @save_sql_mode= @@sql_mode;
+SET sql_mode = 'ONLY_FULL_GROUP_BY';
+SELECT name, test, score,
+AVG(score) OVER (PARTITION BY test) AS average_by_test
+FROM t1
+ORDER BY test, name;
+name test score average_by_test
+Chun SQL 75 65.2500
+Esben SQL 43 65.2500
+Kaolin SQL 56 65.2500
+Tatiana SQL 87 65.2500
+Chun Tuning 73 68.7500
+Esben Tuning 31 68.7500
+Kaolin Tuning 88 68.7500
+Tatiana Tuning 83 68.7500
+set @@sql_mode= @save_sql_mode;
+SELECT name, test, score,
+AVG(score) OVER (PARTITION BY test) AS average_by_test
+FROM t1
+ORDER BY test, name;
+name test score average_by_test
+Chun SQL 75 65.2500
+Esben SQL 43 65.2500
+Kaolin SQL 56 65.2500
+Tatiana SQL 87 65.2500
+Chun Tuning 73 68.7500
+Esben Tuning 31 68.7500
+Kaolin Tuning 88 68.7500
+Tatiana Tuning 83 68.7500
+drop table t1;
+#
+# MDEV-12575: Server crash in AGGR_OP::put_record or in JOIN_CACHE::free
+# or Invalid write in JOIN::make_aggr_tables_info
+#
+SELECT DISTINCT BIT_OR(100) OVER () FROM dual
+GROUP BY LEFT('2018-08-24', 100) order by 1+2;
+BIT_OR(100) OVER ()
+100
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT * FROM (
+SELECT
+ROW_NUMBER() OVER(), i, sum(i)
+FROM t1
+WHERE 1=0
+limit 0
+) AS sq;
+ROW_NUMBER() OVER() i sum(i)
+SELECT * FROM (
+SELECT
+ROW_NUMBER() OVER(), i, sum(i)
+FROM t1
+WHERE 1=0
+GROUP BY i
+) AS sq;
+ROW_NUMBER() OVER() i sum(i)
+drop table t1;
+create table t1 (a int);
+explain
+select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup;
+1 row_number() over (order by 1)
+drop table t1;
+explain
+SELECT DISTINCT BIT_OR(100) OVER () FROM dual
+GROUP BY LEFT('2018-08-24', 100) WITH ROLLUP
+HAVING @A := 'qwerty';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+SELECT DISTINCT BIT_OR(100) OVER () FROM dual
+GROUP BY LEFT('2018-08-24', 100) WITH ROLLUP
+HAVING @A := 'qwerty';
+BIT_OR(100) OVER ()
+explain
+SELECT DISTINCT BIT_OR(100) OVER () FROM dual
+GROUP BY LEFT('2018-08-24', 100)
+HAVING @A := 'qwerty';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+SELECT DISTINCT BIT_OR(100) OVER () FROM dual
+GROUP BY LEFT('2018-08-24', 100)
+HAVING @A := 'qwerty';
+BIT_OR(100) OVER ()
+create table t1 (a int);
+explain
+SELECT DISTINCT BIT_OR(100) OVER () FROM t1
+GROUP BY LEFT('2018-08-24', 100) having 1=1 limit 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit
+drop table t1;
+#
+# MDEV-13170: Database service (MySQL) stops after update with trigger
+#
+CREATE TABLE t1 ( t1_id int, point_id int, ml_id int, UNIQUE KEY t1_ml_u (ml_id,point_id)) ;
+INSERT INTO t1 VALUES (1,1,8884),(2,1,8885);
+CREATE TABLE t2 ( db_time datetime, au_nr int, col_id int, new_val int);
+CREATE TABLE t3 (id1 int, id2 int, d1 int);
+CREATE TRIGGER t1_aurtrg AFTER UPDATE ON t1 FOR EACH ROW begin
+CREATE OR REPLACE TEMPORARY TABLE trg_u AS
+WITH l AS
+(SELECT a.*,
+Max(t2.col_id) over (PARTITION BY a.d1),
+Max(t2.new_val) over (PARTITION BY a.d1)
+FROM
+(SELECT d1 , id1, id2 FROM t3) a
+JOIN t2 ON (a.d1=t2.db_time AND a.id1=t2.au_nr))
+SELECT 1;
+END;//
+update t1 set ml_id=8884 where point_id=1;
+ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u'
+update t1 set ml_id=8884 where point_id=1;
+ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u'
+drop table t1, t2,t3;
+CREATE TABLE t1 (i INT, a char);
+INSERT INTO t1 VALUES (1, 'a'),(2, 'b');
+create view v1 as select * from t1;
+PREPARE stmt FROM "SELECT i, row_number() over (partition by i order by i) FROM v1";
+execute stmt;
+i row_number() over (partition by i order by i)
+1 1
+2 1
+deallocate prepare stmt;
+drop table t1;
+drop view v1;
+#
+# MDEV-17676: Assertion `inited==NONE || (inited==RND && scan)' failed in handler::ha_rnd_init
+#
+CREATE TABLE t1 (b1 text NOT NULL);
+INSERT INTO t1 VALUES ('2'),('1');
+EXPLAIN
+SELECT DISTINCT MIN(b1) OVER () FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT DISTINCT MIN(b1) OVER () FROM t1;
+MIN(b1) OVER ()
+1
+drop table t1;
+#
+# MDEV-15424: Unreasonal SQL Error (1356) on select from view
+#
+create table t1 (id int, n1 int);
+insert into t1 values (1,1), (2,1), (3,2), (4,4);
+create view v1 as SELECT ifnull(max(n1) over (partition by n1),'aaa') FROM t1;
+explain select * from v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using temporary
+select * from v1;
+ifnull(max(n1) over (partition by n1),'aaa')
+1
+1
+2
+4
+drop table t1;
+drop view v1;
+#
+# MDEV-18431: Select max + row_number giving incorrect result
+#
+create table t1 (id int, v int);
+insert into t1 values (1, 1), (1,2), (1,3), (2, 1), (2, 2);
+select e.id,
+(select max(t1.v) from t1 where t1.id=e.id) as a,
+row_number() over (partition by e.id order by e.v) as b,
+(select max(t1.v) from t1 where t1.id=e.id) + (row_number() over (partition by e.id order by e.v)) as sum_a_b
+from t1 e;
+id a b sum_a_b
+1 3 1 4
+1 3 2 5
+1 3 3 6
+2 2 1 3
+2 2 2 4
+drop table t1;
+#
+# MDEV-15837: Assertion `item1->type() == Item::FIELD_ITEM && item2->type() == Item::FIELD_ITEM'
+# failed in compare_order_elements function
+#
+CREATE TABLE t1 (a1 int);
+insert into t1 values (1),(2),(3);
+SELECT rank() OVER (ORDER BY 1), ROW_NUMBER() OVER (ORDER BY (EXPORT_SET(5,'Y','N',',',4))) FROM t1;
+rank() OVER (ORDER BY 1) ROW_NUMBER() OVER (ORDER BY (EXPORT_SET(5,'Y','N',',',4)))
+1 1
+1 2
+1 3
+drop table t1;
+#
+# MDEV-17781: Server crashes in next_linear_tab
+#
+CREATE TABLE t1 (i1 int);
+explain
+(SELECT AVG(0) OVER (), MAX('2') FROM t1)
+UNION ALL
+(SELECT AVG(0) OVER (), MAX('2') FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+(SELECT AVG(0) OVER (), MAX('2') FROM t1)
+UNION ALL
+(SELECT AVG(0) OVER (), MAX('2') FROM t1);
+AVG(0) OVER () MAX('2')
+0.0000 NULL
+0.0000 NULL
+drop table t1;
+#
+# MDEV-14791: Crash with order by expression containing window functions
+#
+CREATE TABLE t1 (b1 int, b2 int);
+INSERT INTO t1 VALUES (1,1),(0,0);
+explain
+SELECT b1 from t1 order by row_number() over (ORDER BY b2) + 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+SELECT b1 from t1 order by row_number() over (ORDER BY b2) + 1;
+b1
+0
+1
+explain
+SELECT b1 from t1 order by row_number() over (ORDER BY b2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+SELECT b1 from t1 order by row_number() over (ORDER BY b2);
+b1
+0
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, c int);
+INSERT INTO t1 VALUES (2,3,207), (1,21,909), (7,13,312), (8,64,248);
+explain
+SELECT * FROM t1 ORDER BY max(t1.a) over (partition by c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+SELECT * FROM t1 ORDER BY max(t1.a) over (partition by c);
+a b c
+1 21 909
+2 3 207
+7 13 312
+8 64 248
+explain
+SELECT max(t1.a) over (partition by c) as x, b, c from t1 order by max(t1.a) over (partition by c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+SELECT max(t1.a) over (partition by c) as x, b, c from t1 order by max(t1.a) over (partition by c);
+x b c
+1 21 909
+2 3 207
+7 13 312
+8 64 248
+drop table t1;
+#
+# MDEV-18373: DENSE_RANK is not calculated correctly
+#
+create table t1 (a int, b int);
+insert into t1 values (60, 1515),(60, 2000),(70, 2000),(55, 1600);
+select b, dense_rank() over (order by sum(a)) from t1 group by b;
+b dense_rank() over (order by sum(a))
+1515 2
+1600 1
+2000 3
+select b, dense_rank() over (order by sum(a)+1) from t1 group by b;
+b dense_rank() over (order by sum(a)+1)
+1515 2
+1600 1
+2000 3
+select b, row_number() over (partition by sum(a)) from t1 group by b;
+b row_number() over (partition by sum(a))
+1515 1
+1600 1
+2000 1
+select b, row_number() over (partition by sum(a)+1) from t1 group by b;
+b row_number() over (partition by sum(a)+1)
+1515 1
+1600 1
+2000 1
+drop table t1;
+#
+# MDEV-18015: Assertion `global_status_var.global_memory_used == 0' failed when using UDF,
+# window functions and views
+#
+create table t1 (id int, n1 int);
+insert into t1 values (1,1),(2,1),(3,2),(4,4);
+explain
+select max(n1) over (partition by 'abc') from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary
+select max(n1) over (partition by 'abc') from t1;
+max(n1) over (partition by 'abc')
+4
+4
+4
+4
+explain
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+rank() over (partition by 'abc' order by 'xyz')
+1
+1
+1
+1
+drop table t1;
+#
+# MDEV-19380: ASAN heap-use-after-free in Protocol::net_store_data
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+SELECT (SELECT MIN('foo') OVER() FROM t1 LIMIT 1) as x;
+x
+foo
+drop table t1;
+#
+# MDEV-16579: Wrong result of query using DISTINCT COUNT(*) OVER (*)
+#
+CREATE TABLE t1 (i int) ;
+INSERT INTO t1 VALUES (1),(0),(1),(2),(0),(1),(2),(1),(2);
+SELECT DISTINCT COUNT(*) OVER (), MOD(MIN(i),2) FROM t1 GROUP BY i ;
+COUNT(*) OVER () MOD(MIN(i),2)
+3 0
+3 1
+drop table t1;
+#
+# MDEV-21318: Wrong results with window functions and implicit grouping
+#
+CREATE TABLE t1 (a INT);
+#
+# With empty const table
+# The expected result here is 1, NULL
+#
+explain
+SELECT row_number() over(), sum(1) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found; Using temporary
+SELECT row_number() over(), sum(1) FROM t1;
+row_number() over() sum(1)
+1 NULL
+insert into t1 values (2);
+#
+# Const table has 1 row, but still impossible where
+# The expected result here is 1, NULL
+#
+EXPLAIN SELECT row_number() over(), sum(1) FROM t1 where a=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT row_number() over(), sum(1) FROM t1 where a=1;
+row_number() over() sum(1)
+1 NULL
+#
+# Impossible HAVING
+# Empty result is expected
+#
+EXPLAIN SELECT row_number() over(), sum(1) FROM t1 where a=1 having 1=0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+SELECT row_number() over(), sum(1) FROM t1 where a=1 having 1=0;
+row_number() over() sum(1)
+#
+# const table has 1 row, no impossible where
+# The expected result here is 1, 2
+#
+EXPLAIN SELECT row_number() over(), sum(a) FROM t1 where a=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary
+SELECT row_number() over(), sum(a) FROM t1 where a=2;
+row_number() over() sum(a)
+1 2
+drop table t1;
+#
+# Impossible Where
+#
+create table t1(a int);
+insert into t1 values (1);
+#
+# Expected result is NULL, 0, NULL
+#
+EXPLAIN SELECT MAX(a) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT MAX(a) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE;
+MAX(a) OVER () COUNT(a) abs(a)
+NULL 0 NULL
+#
+# Expected result is 1, 0, NULL
+#
+EXPLAIN
+SELECT MAX(1) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT MAX(1) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE;
+MAX(1) OVER () COUNT(a) abs(a)
+1 0 NULL
+drop table t1;
+#
+# MDEV-22461: JOIN::make_aggr_tables_info(): Assertion `select_options & (1ULL << 17)' failed.
+#
+CREATE TEMPORARY TABLE t0 (a INT PRIMARY KEY ) ;
+INSERT INTO t0 VALUES (1),(2),(3);
+SELECT a FROM t0
+WHERE a < 8
+GROUP BY 1.5
+WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
+a
+1
+SELECT a, ROW_NUMBER() OVER v2
+FROM t0
+WHERE a < 8
+GROUP BY 1.5
+WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC );
+a ROW_NUMBER() OVER v2
+1 1
+drop table t0;
+#
+# MDEV-16230:Server crashes when Analyze format=json is run with a window function with
+# empty PARTITION BY and ORDER BY clauses
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+ANALYZE FORMAT=JSON SELECT row_number() OVER() FROM t1;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "window_functions_computation": {
+ "sorts": {
+ "filesort": {
+ "sort_key": "`row_number() OVER()`",
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "r_used_priority_queue": false,
+ "r_output_rows": 3,
+ "r_buffer_size": "REPLACED",
+ "r_sort_mode": "sort_key,rowid"
+ }
+ },
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 3,
+ "r_rows": 3,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ }
+ }
+}
+SELECT row_number() OVER() FROM t1;
+row_number() OVER()
+1
+2
+3
+DROP TABLE t1;
+#
+# MDEV-22984: Throw an error when arguments to window functions are window functions
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
+SELECT NTILE(MAX(a) OVER (PARTITION BY a)) OVER (PARTITION BY a ORDER BY b) FROM t1;
+ERROR HY000: Window functions can not be used as arguments to group functions.
+SELECT FIRST_VALUE(MAX(a) OVER (PARTITION BY a)) OVER (ORDER BY a) AS x FROM t1 GROUP BY a;
+ERROR HY000: Window functions can not be used as arguments to group functions.
+DROP TABLE t1;
+#
+# MDEV-12059: Assertion `precision > 0' failed with a window function or window aggregate function
+#
+CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED);
+INSERT INTO t1 VALUES (1),(2);
+SELECT MIN(d) OVER () FROM t1;
+MIN(d) OVER ()
+1
+1
+DROP TABLE t1;
+#
+# MDEV-22463: Element_type &Bounds_checked_array<Item *>::operator[](size_t) [Element_type = Item *]:
+# Assertion `n < m_size' failed
+#
+CREATE TABLE t1 (a INT, b INT, c INT, d INT, e INT, f INT, g int, h INT, i INT);
+INSERT INTO t1 SELECT seq,seq,seq,seq, seq,seq,seq,seq,seq FROM seq_1_to_5;
+SELECT ROW_NUMBER() OVER w2 FROM t1 WINDOW w2 AS (PARTITION BY -1,0,1,2,3,4,5,6);
+ROW_NUMBER() OVER w2
+1
+2
+3
+4
+5
+SELECT a FROM t1 ORDER BY ROW_NUMBER() OVER (PARTITION BY -1,1,0,2,3,4,5,6,7,8);
+a
+1
+2
+3
+4
+5
+SELECT a,b FROM t1 WINDOW w2 AS (PARTITION BY -1,1,0,2,3,4);
+a b
+1 1
+2 2
+3 3
+4 4
+5 5
+SELECT ROW_NUMBER() OVER w2 FROM t1 WINDOW w2 AS (PARTITION BY -1,0,1,2,3,4,5,6);
+ROW_NUMBER() OVER w2
+1
+2
+3
+4
+5
+DROP TABLE t1;
+#
+# MDEV-18916: crash in Window_spec::print_partition() with decimals
+#
+SELECT cast((rank() over w1) as decimal (53,56));
+ERROR 42000: Too big scale 56 specified for 'rank() over w1'. Maximum is 38
+SELECT cast((rank() over w1) as decimal (53,30));
+ERROR HY000: Window specification with name 'w1' is not defined
+#
+# MDEV-15180: server crashed with NTH_VALUE()
+#
+CREATE TABLE t1 (i1 int, a int);
+INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3);
+CREATE TABLE t2 (i2 int);
+INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3);
+CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ;
+SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1;
+NTH_VALUE(i1, i1) OVER (PARTITION BY i1)
+1
+1
+NULL
+NULL
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# End of 10.2 tests
+#
+#
+# MDEV-16489 when lead() returns null on a datetime field, the result is treated as the literal string '[NULL]'
+#
+CREATE TABLE t1 (d datetime);
+INSERT INTO t1 VALUES ('2018-01-01 00:00:00'),('2018-02-01 00:00:00');
+SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1;
+d x
+2018-01-01 00:00:00 2018-02-01 00:00:00
+2018-02-01 00:00:00 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (d time);
+INSERT INTO t1 VALUES ('00:00:01'),('00:00:02');
+SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1;
+d x
+00:00:01 00:00:02
+00:00:02 NULL
+DROP TABLE t1;
+#
+# MDEV-20351 Window function BIT_OR() OVER (..) return a wrong data type
+#
+CREATE TABLE t1 (pk INT, a INT, b BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (1, 0, 1), (2, 0, 18446744073709551615);
+CREATE TABLE t2 AS
+SELECT pk, a, bit_or(b) AS bit_or FROM t1 GROUP BY pk;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `pk` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `bit_or` bigint(21) unsigned NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+pk a b
+1 0 1
+2 0 18446744073709551615
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 AS
+SELECT pk, a, BIT_OR(b) OVER (PARTITION BY a ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS bit_or
+FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `pk` int(11) DEFAULT NULL,
+ `a` int(11) DEFAULT NULL,
+ `bit_or` bigint(21) unsigned NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+pk a bit_or
+1 0 18446744073709551615
+2 0 18446744073709551615
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# End of 10.3 tests
+#
+#
+# MDEV-16722: Assertion `type() != NULL_ITEM' failed
+#
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+SELECT row_number() OVER (order by a) FROM t1 order by NAME_CONST('myname',NULL);
+row_number() OVER (order by a)
+1
+2
+3
+drop table t1;
+#
+# MDEV-23867: select crash in compute_window_func
+#
+set @save_sort_buffer_size=@@sort_buffer_size;
+set sort_buffer_size= 2000;
+CREATE TABLE t1( a INT, b INT, c INT);
+INSERT INTO t1 select seq, seq, seq from seq_1_to_5000;
+CREATE TABLE t2( a INT, b INT, c INT);
+INSERT INTO t2 SELECT a, b, ROW_NUMBER() OVER (PARTITION BY b) FROM t1;
+SELECT COUNT(*), MAX(c) FROM t2;
+COUNT(*) MAX(c)
+5000 1
+CREATE TABLE t3( a INT, b INT, c INT);
+INSERT INTO t3 SELECT a, b, SUM(a) OVER () FROM t1;
+SELECT COUNT(*), MAX(c) FROM t3;
+COUNT(*) MAX(c)
+5000 12502500
+set @@sort_buffer_size=@save_sort_buffer_size;
+DROP TABLE t1,t2,t3;
+# end of 10.2 test
#
# MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON
#
@@ -16,3 +3973,4 @@ count(*)
5000
set @@sort_buffer_size=@save_sort_buffer_size;
drop table t1;
+# End of 10.4 tests
diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test b/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test
index d902fa38508..5fe6f686576 100644
--- a/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test
+++ b/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test
@@ -37,8 +37,10 @@ insert into innodb_compact select * from innodb_normal;
insert into innodb_dynamic select * from innodb_normal;
commit;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED';
---source include/wait_condition.inc
+FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES;
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED';
--let $restart_parameters=--innodb-encrypt-tables=OFF
--source include/restart_mysqld.inc
@@ -52,8 +54,13 @@ alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEF
show create table innodb_compact;
alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT;
show create table innodb_dynamic;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_DECOMPRESSED';
---source include/wait_condition.inc
+
+FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES;
+
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_PAGE_DECOMPRESSED';
drop procedure innodb_insert_proc;
drop table innodb_normal;
diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test
index 5b472094653..a736c7292ad 100644
--- a/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test
+++ b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test
@@ -18,47 +18,34 @@ show create table innodb_compressed;
show create table innodb_dynamic;
show create table innodb_redundant;
-delimiter //;
-create procedure innodb_insert_proc (repeat_count int)
-begin
- declare current_num int;
- set current_num = 0;
- while current_num < repeat_count do
- insert into innodb_normal values(current_num, substring(MD5(RAND()), -64));
- set current_num = current_num + 1;
- end while;
-end//
-delimiter ;//
-commit;
+FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES;
-begin;
-call innodb_insert_proc(2000);
-insert into innodb_compact select * from innodb_normal;
-insert into innodb_compressed select * from innodb_normal;
-insert into innodb_dynamic select * from innodb_normal;
-insert into innodb_redundant select * from innodb_normal;
-commit;
-
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
---source include/wait_condition.inc
-
-# Note there that these variables are updated only when real I/O is done, thus they are not reliable
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
+select variable_value > 0 from information_schema.global_status
+where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
--source include/restart_mysqld.inc
-update innodb_normal set c1 = c1 +1;
-update innodb_compact set c1 = c1 + 1;
-update innodb_compressed set c1 = c1 + 1;
-update innodb_dynamic set c1 = c1 + 1;
-update innodb_redundant set c1 = c1 + 1;
+BEGIN;
+INSERT INTO innodb_normal SET c1 = 1;
+INSERT INTO innodb_compact SET c1 = 1;
+INSERT INTO innodb_compressed SET c1 = 1;
+INSERT INTO innodb_dynamic SET c1 = 1;
+INSERT INTO innodb_redundant SET c1 = 1;
+COMMIT;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
---source include/wait_condition.inc
+FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES;
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
+select variable_name from information_schema.global_status
+where variable_value > 0 and variable_name
+IN ('INNODB_NUM_PAGES_ENCRYPTED','INNODB_NUM_PAGES_DECRYPTED');
SET GLOBAL innodb_encrypt_tables=OFF;
alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT;
@@ -70,13 +57,12 @@ show create table innodb_dynamic;
alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT;
show create table innodb_redundant;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_DECRYPTED';
---source include/wait_condition.inc
-
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
+FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES;
+FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES;
-drop procedure innodb_insert_proc;
drop table innodb_normal;
drop table innodb_compact;
drop table innodb_compressed;
diff --git a/mysql-test/suite/encryption/t/innodb-remove-encryption.test b/mysql-test/suite/encryption/t/innodb-remove-encryption.test
index 90c6925d125..aeafd99325b 100644
--- a/mysql-test/suite/encryption/t/innodb-remove-encryption.test
+++ b/mysql-test/suite/encryption/t/innodb-remove-encryption.test
@@ -29,6 +29,7 @@ create table t1(a int not null primary key, b char(200)) engine=innodb;
--source include/wait_condition.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--echo # Success!
@@ -41,6 +42,7 @@ SET GLOBAL innodb_encrypt_tables = off;
--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING = 0;
--source include/wait_condition.inc
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
@@ -51,6 +53,7 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
--let $restart_parameters=--skip-file-key-management --innodb-encrypt-tables=OFF --innodb-encryption-threads=0 --innodb-tablespaces-encryption
-- source include/restart_mysqld.inc
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
index bc4c43e1ce8..ef38560c469 100644
--- a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
+++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
@@ -26,6 +26,7 @@ let $restart_parameters= --innodb_encryption_threads=5 --innodb_encryption_rotat
--source include/wait_condition.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--echo # Restart the server with innodb_encryption_rotate_key_age= 0
@@ -45,6 +46,7 @@ create table t4 (f1 int not null)engine=innodb encrypted=NO;
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--echo # Disable encryption when innodb_encryption_rotate_key_age is 0
@@ -57,6 +59,7 @@ set global innodb_encrypt_tables = OFF;
--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING = 0;
--source include/wait_condition.inc
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
--echo # Display only encrypted create tables (t3)
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
@@ -73,11 +76,13 @@ set global innodb_encrypt_tables = ON;
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
--echo # Display only unencrypted create tables (t4)
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--let $restart_parameters=
-- source include/restart_mysqld.inc
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
+--sorted_result
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
DROP TABLE t4, t3, t2, t1;
diff --git a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
index ad1a9ea8671..57c8721282f 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
@@ -1,6 +1,8 @@
-- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc
-- source include/not_embedded.inc
+# This test is too slow for valgrind and causes innnodb semaphores to time out
+-- source include/not_valgrind.inc
let $innodb_encrypt_tables_orig = `SELECT @@innodb_encrypt_tables`;
let $innodb_encryption_threads_orig = `SELECT @@innodb_encryption_threads`;
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt
index bcff011eb82..9fe990f7260 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt
+++ b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt
@@ -3,6 +3,5 @@
--innodb-encryption-rotate-key-age=15
--innodb-encryption-threads=4
--innodb-tablespaces-encryption
+--innodb-max-dirty-pages-pct_lwm=0
--innodb-max-dirty-pages-pct=0.001
-
-
diff --git a/mysql-test/suite/encryption/t/tempfiles_encrypted.test b/mysql-test/suite/encryption/t/tempfiles_encrypted.test
index 96b981c1c06..7628442f884 100644
--- a/mysql-test/suite/encryption/t/tempfiles_encrypted.test
+++ b/mysql-test/suite/encryption/t/tempfiles_encrypted.test
@@ -5,9 +5,31 @@
source include/have_file_key_management_plugin.inc;
source include/have_sequence.inc;
source include/have_innodb.inc;
-
+
select @@encrypt_tmp_files;
+--source main/win.test
+
+--echo #
+--echo # MDEV-23867: select crash in compute_window_func
+--echo #
+
+set @save_sort_buffer_size=@@sort_buffer_size;
+
+set sort_buffer_size= 2000;
+CREATE TABLE t1( a INT, b INT, c INT);
+INSERT INTO t1 select seq, seq, seq from seq_1_to_5000;
+CREATE TABLE t2( a INT, b INT, c INT);
+INSERT INTO t2 SELECT a, b, ROW_NUMBER() OVER (PARTITION BY b) FROM t1;
+SELECT COUNT(*), MAX(c) FROM t2;
+CREATE TABLE t3( a INT, b INT, c INT);
+INSERT INTO t3 SELECT a, b, SUM(a) OVER () FROM t1;
+SELECT COUNT(*), MAX(c) FROM t3;
+set @@sort_buffer_size=@save_sort_buffer_size;
+DROP TABLE t1,t2,t3;
+
+--echo # end of 10.2 test
+
--echo #
--echo # MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON
--echo #
@@ -21,3 +43,5 @@ select count(*) from (select a, b, c, ROW_NUMBER() OVER (PARTITION BY a) FROM t1
set @@sort_buffer_size=@save_sort_buffer_size;
drop table t1;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result
index 7a407d8aeef..28736515327 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.result
+++ b/mysql-test/suite/federated/federatedx_create_handlers.result
@@ -378,6 +378,50 @@ DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4;
connection slave;
DROP TABLE federated.t1, federated.t2;
connection default;
+#
+# MDEV-23778: Derived handler used for big derived tables
+#
+connection slave;
+CREATE TABLE federated.t1 (
+a varchar(100) NOT NULL default '123'
+)
+DEFAULT CHARSET=latin1;
+CREATE TABLE federated.t2 LIKE federated.t1;
+BEGIN NOT ATOMIC
+DECLARE i INT DEFAULT 0;
+START TRANSACTION;
+WHILE i < 70000 DO
+INSERT INTO federated.t1 VALUES (i);
+SET i = i + 1;
+END WHILE;
+COMMIT;
+END
+$$
+connection master;
+CREATE TABLE federated.t1 (
+a varchar(100) NOT NULL default '123'
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
+CREATE TABLE federated.t2 (
+a varchar(100) NOT NULL default '123'
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t2';
+SELECT COUNT(DISTINCT a) FROM federated.t1;
+COUNT(DISTINCT a)
+70000
+INSERT INTO federated.t2
+SELECT * FROM (SELECT * FROM federated.t1 LIMIT 100) dt;
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+COUNT(DISTINCT a)
+100
+TRUNCATE TABLE federated.t2;
+INSERT INTO federated.t2
+SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt;
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+COUNT(DISTINCT a)
+70000
set global federated_pushdown=0;
connection master;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test
index d765588b79b..4b5789e1d96 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.test
+++ b/mysql-test/suite/federated/federatedx_create_handlers.test
@@ -208,6 +208,63 @@ DROP TABLE federated.t1, federated.t2;
connection default;
+--echo #
+--echo # MDEV-23778: Derived handler used for big derived tables
+--echo #
+
+connection slave;
+
+CREATE TABLE federated.t1 (
+ a varchar(100) NOT NULL default '123'
+)
+DEFAULT CHARSET=latin1;
+
+CREATE TABLE federated.t2 LIKE federated.t1;
+
+DELIMITER $$;
+BEGIN NOT ATOMIC
+ DECLARE i INT DEFAULT 0;
+ START TRANSACTION;
+ WHILE i < 70000 DO
+ INSERT INTO federated.t1 VALUES (i);
+ SET i = i + 1;
+ END WHILE;
+ COMMIT;
+END
+$$
+
+DELIMITER ;$$
+
+connection master;
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t1 (
+ a varchar(100) NOT NULL default '123'
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
+
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t2 (
+ a varchar(100) NOT NULL default '123'
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2';
+
+SELECT COUNT(DISTINCT a) FROM federated.t1;
+
+INSERT INTO federated.t2
+ SELECT * FROM (SELECT * FROM federated.t1 LIMIT 100) dt;
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+
+TRUNCATE TABLE federated.t2;
+INSERT INTO federated.t2
+ SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt;
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+
set global federated_pushdown=0;
source include/federated_cleanup.inc;
diff --git a/mysql-test/suite/funcs_1/r/is_routines_embedded.result b/mysql-test/suite/funcs_1/r/is_routines_embedded.result
index 992a5884d02..983ad198052 100644
--- a/mysql-test/suite/funcs_1/r/is_routines_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_routines_embedded.result
@@ -197,7 +197,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL
SELECT * FROM db_datadict_2.res_6_408002_2;
END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
-check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
+check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin
set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci
@@ -213,7 +213,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL
SELECT * FROM db_datadict_2.res_6_408002_2;
END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
-check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
+check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin
set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci
@@ -229,7 +229,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL
SELECT * FROM db_datadict_2.res_6_408002_2;
END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
-check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
+check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert'); SELECT * FROM INFORMATION_SCHEMA.ROUTINES; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.proc, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8 utf8_general_ci latin1_swedish_ci
AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin
set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index baff20752be..d940c702d54 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -16,6 +16,7 @@ MDEV-16509 : MDEV-21523 galera.MDEV-16509
MDEV-20225 : MDEV-20886 galera.MDEV-20225
MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently with Galera/replication victim kill
MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002
+MW-328A : MDEV-22666?
MW-328B : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002
MW-329 : MDEV-19962 Galera test failure on MW-329
galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults
@@ -27,7 +28,6 @@ galera_ftwrl : MDEV-21525 galera.galera_ftwrl
galera_gcache_recover_manytrx : MDEV-18834 Galera test failure
galera_kill_largechanges : MDEV-18179 Galera test failure on galera.galera_kill_largechanges
galera_kill_nochanges : MDEV-18280 Galera test failure on galera_split_brain and galera_kill_nochanges
-galera_load_data : MDEV-19968 galera.galera_load_data
galera_many_tables_nopk : MDEV-18182 Galera test failure on galera.galera_many_tables_nopk
galera_mdl_race : MDEV-21524 galera.galera_mdl_race
galera_parallel_simple : MDEV-20318 galera.galera_parallel_simple fails
@@ -41,6 +41,7 @@ galera_toi_truncate : MDEV-22996 Hang on galera_toi_truncate test case
galera_var_node_address : MDEV-20485 Galera test failure
galera_var_notify_cmd : MDEV-21905 Galera test galera_var_notify_cmd causes hang
galera_var_reject_queries : assertion in inline_mysql_socket_send
+galera_var_replicate_myisam_on : MDEV-24062 Galera test failure on galera_var_replicate_myisam_on
galera_var_retry_autocommit: MDEV-18181 Galera test failure on galera.galera_var_retry_autocommit
galera_wan : MDEV-17259 Test failure on galera.galera_wan
lp1376747-4 : MDEV-21911 Galera test failure on lp1376747-4
@@ -48,4 +49,3 @@ partition : MDEV-19958 Galera test failure on galera.partition
query_cache: MDEV-15805 Test failure on galera.query_cache
sql_log_bin : MDEV-21491 galera.sql_log_bin
versioning_trx_id : MDEV-18590 galera.versioning_trx_id
-MW-328A : MDEV-22666?
diff --git a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
index a0d128f5fa3..94825107741 100644
--- a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
+++ b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
@@ -19,10 +19,18 @@ connection node_2;
Performing --wsrep-recover ...
Using --wsrep-start-position when starting mysqld ...
connection node_1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5
+connection node_2;
+SET SESSION wsrep_sync_wait = 15;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5
include/diff_servers.inc [servers=1 2]
connection node_1;
DROP TABLE t1;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
-include/assert_grep.inc [IST first seqno [24] not found from cache, falling back to SST]
+include/assert_grep.inc [not found from cache, falling back to SST]
connection node_2;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
diff --git a/mysql-test/suite/galera/r/galera_load_data.result b/mysql-test/suite/galera/r/galera_load_data.result
index 42795fab7a7..84e96f8a36c 100644
--- a/mysql-test/suite/galera/r/galera_load_data.result
+++ b/mysql-test/suite/galera/r/galera_load_data.result
@@ -3,7 +3,7 @@ connection node_1;
connection node_1;
create database cardtest02;
use cardtest02;
-CREATE TABLE `cardtest_tbl` (
+CREATE TABLE cardtest_tbl (
`id` bigint(18) NOT NULL AUTO_INCREMENT,
`course` bigint(18) NOT NULL,
`name` varchar(200) DEFAULT NULL,
@@ -24,24 +24,33 @@ CREATE TABLE `cardtest_tbl` (
`type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1324 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
-LOCK TABLES `cardtest_tbl` WRITE;
-ALTER TABLE `cardtest_tbl` DISABLE KEYS;
+LOCK TABLES cardtest_tbl WRITE;
+ALTER TABLE cardtest_tbl DISABLE KEYS;
Warnings:
Note 1031 Storage engine InnoDB of the table `cardtest02`.`cardtest_tbl` doesn't have this option
-INSERT INTO `cardtest_tbl` VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL);
-ALTER TABLE `cardtest_tbl` ENABLE KEYS;
+INSERT INTO cardtest_tbl VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL);
+ALTER TABLE cardtest_tbl ENABLE KEYS;
Warnings:
Note 1031 Storage engine InnoDB of the table `cardtest02`.`cardtest_tbl` doesn't have this option
UNLOCK TABLES;
use cardtest02;
-select count(*) from cardtest_tbl;
-count(*)
+ANALYZE TABLE cardtest_tbl;
+Table Op Msg_type Msg_text
+cardtest02.cardtest_tbl analyze status Engine-independent statistics collected
+cardtest02.cardtest_tbl analyze Warning Engine-independent statistics are not collected for column 'intro'
+cardtest02.cardtest_tbl analyze status OK
+SELECT COUNT(*) AS EXPECT_301 FROM cardtest_tbl;
+EXPECT_301
301
connection node_2;
-set session wsrep_sync_wait=15;
use cardtest02;
-select count(*) from cardtest_tbl;
-count(*)
+ANALYZE TABLE cardtest_tbl;
+Table Op Msg_type Msg_text
+cardtest02.cardtest_tbl analyze status Engine-independent statistics collected
+cardtest02.cardtest_tbl analyze Warning Engine-independent statistics are not collected for column 'intro'
+cardtest02.cardtest_tbl analyze status OK
+SELECT COUNT(*) AS EXPECT_301 FROM cardtest_tbl;
+EXPECT_301
301
connection node_1;
use test;
diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_lost_found.result b/mysql-test/suite/galera/r/galera_sst_mariabackup_lost_found.result
new file mode 100644
index 00000000000..2d5705c6e35
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_lost_found.result
@@ -0,0 +1,39 @@
+connection node_2;
+connection node_1;
+connection node_1;
+connection node_2;
+connection node_2;
+Shutting down server ...
+connection node_1;
+CREATE DATABASE `lost+found`;
+USE `lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `lost+found`.t1;
+id
+1
+2
+CREATE DATABASE `#mysql50#not_lost+found`;
+USE `#mysql50#not_lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `#mysql50#not_lost+found`.t1;
+id
+1
+2
+Cleaning var directory ...
+connection node_2;
+Starting server ...
+SELECT * FROM `lost+found`.t1;
+id
+1
+2
+SELECT * FROM `#mysql50#not_lost+found`.t1;
+id
+1
+2
+connection node_1;
+DROP DATABASE `lost+found`;
+DROP DATABASE `#mysql50#not_lost+found`;
+disconnect node_2;
+disconnect node_1;
diff --git a/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result b/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result
index 716af033e7a..ad28f5a426e 100644
--- a/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result
+++ b/mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result
@@ -107,6 +107,135 @@ i
1
DROP TABLE t1;
connection node_1;
-SET GLOBAL wsrep_replicate_myisam = 0;
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+PREPARE upd from 'update t1 set b = 100 where id = 5';
+PREPARE ins from 'insert into t1 values (11,11)';
+PREPARE del from 'delete from t1 where id = 4';
+PREPARE rep from 'replace into t1 values (12,12),(6,600)';
+EXECUTE upd;
+EXECUTE ins;
+EXECUTE del;
+EXECUTE rep;
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 2
+3 3
+5 100
+6 600
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+connection node_2;
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 2
+3 3
+5 100
+6 600
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+DROP TABLE t1;
+connection node_1;
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+CREATE PROCEDURE proc()
+BEGIN
+UPDATE t1 set b = 100 WHERE id = 5;
+INSERT INTO t1 VALUES (11,11);
+DELETE FROM t1 WHERE id = 4;
+REPLACE INTO t1 VALUES (12,12),(6,600);
+COMMIT;
+END|
+CALL proc();
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 2
+3 3
+5 100
+6 600
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+connection node_2;
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 2
+3 3
+5 100
+6 600
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+DROP PROCEDURE proc;
+DROP TABLE t1;
+connection node_1;
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.b);
+CREATE TRIGGER tr2 BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, OLD.b),(NULL, NEW.b);
+CREATE TRIGGER tr3 BEFORE DELETE ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, OLD.b);
+INSERT INTO t1 VALUES (11,11);
+UPDATE t1 SET b = 200 WHERE id = 2;
+DELETE FROM t1 where id = 5;
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 200
+3 3
+4 4
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+SELECT * FROM t2 ORDER BY id;
+id b
+1 11
+2 2
+3 200
+4 5
+connection node_2;
+SELECT * FROM t1 ORDER BY id;
+id b
+1 1
+2 200
+3 3
+4 4
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+SELECT * FROM t2 ORDER BY id;
+id b
+1 11
+2 2
+3 200
+4 5
+DROP TRIGGER tr1;
+DROP TRIGGER tr2;
+DROP TRIGGER tr3;
+DROP TABLE t1,t2;
+connection node_1;
connection node_2;
-SET GLOBAL wsrep_replicate_myisam = 0;
diff --git a/mysql-test/suite/galera/r/galera_var_trx_fragment_size.result b/mysql-test/suite/galera/r/galera_var_trx_fragment_size.result
new file mode 100644
index 00000000000..be14c53548b
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_var_trx_fragment_size.result
@@ -0,0 +1,95 @@
+connection node_2;
+connection node_1;
+SET SESSION wsrep_trx_fragment_size=DEFAULT;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET SESSION wsrep_trx_fragment_size=0;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET GLOBAL wsrep_trx_fragment_size=DEFAULT;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET GLOBAL wsrep_trx_fragment_size=0;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET GLOBAL wsrep_trx_fragment_size=-1;
+Warnings:
+Warning 1292 Truncated incorrect wsrep_trx_fragment_size value: '-1'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET SESSION wsrep_trx_fragment_size=-1;
+Warnings:
+Warning 1292 Truncated incorrect wsrep_trx_fragment_size value: '-1'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SET GLOBAL wsrep_trx_fragment_size=100;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 0
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET SESSION wsrep_trx_fragment_size=100;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET GLOBAL wsrep_trx_fragment_size='A';
+ERROR 42000: Incorrect argument type to variable 'wsrep_trx_fragment_size'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET SESSION wsrep_trx_fragment_size='A';
+ERROR 42000: Incorrect argument type to variable 'wsrep_trx_fragment_size'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET GLOBAL wsrep_trx_fragment_size=NULL;
+ERROR 42000: Incorrect argument type to variable 'wsrep_trx_fragment_size'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET SESSION wsrep_trx_fragment_size=NULL;
+ERROR 42000: Incorrect argument type to variable 'wsrep_trx_fragment_size'
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+Variable_name Value
+wsrep_trx_fragment_size 100
+SET GLOBAL wsrep_trx_fragment_size=DEFAULT;
diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test
index d728a094f10..6b3e56d8a0f 100644
--- a/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test
+++ b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test
@@ -46,6 +46,12 @@ INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10));
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+SELECT COUNT(*) FROM t1;
+
+--connection node_2
+SET SESSION wsrep_sync_wait = 15;
+SELECT COUNT(*) FROM t1;
+
--let $diff_servers = 1 2
--source include/diff_servers.inc
@@ -56,8 +62,8 @@ DROP TABLE t1;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
# Confirm that IST did not take place
---let $assert_text = IST first seqno [24] not found from cache, falling back to SST
---let $assert_select = IST first seqno [24] not found from cache, falling back to SST
+--let $assert_text = not found from cache, falling back to SST
+--let $assert_select = not found from cache, falling back to SST
--let $assert_count = 1
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_only_after = starting as process
diff --git a/mysql-test/suite/galera/t/galera_load_data.test b/mysql-test/suite/galera/t/galera_load_data.test
index 66526bea5e1..c37920a43c4 100644
--- a/mysql-test/suite/galera/t/galera_load_data.test
+++ b/mysql-test/suite/galera/t/galera_load_data.test
@@ -5,7 +5,7 @@
create database cardtest02;
use cardtest02;
-CREATE TABLE `cardtest_tbl` (
+CREATE TABLE cardtest_tbl (
`id` bigint(18) NOT NULL AUTO_INCREMENT,
`course` bigint(18) NOT NULL,
`name` varchar(200) DEFAULT NULL,
@@ -27,13 +27,13 @@ CREATE TABLE `cardtest_tbl` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1324 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
-LOCK TABLES `cardtest_tbl` WRITE;
-ALTER TABLE `cardtest_tbl` DISABLE KEYS;
+LOCK TABLES cardtest_tbl WRITE;
+ALTER TABLE cardtest_tbl DISABLE KEYS;
-INSERT INTO `cardtest_tbl` VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL);
+INSERT INTO cardtest_tbl VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL);
-ALTER TABLE `cardtest_tbl` ENABLE KEYS;
+ALTER TABLE cardtest_tbl ENABLE KEYS;
UNLOCK TABLES;
use cardtest02;
@@ -45,10 +45,15 @@ let $avg_row_length1 = `SELECT avg_row_length from information_schema.tables WHE
let $data_length1 = `SELECT data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`;
--let $wait_timeout=600
+--let $wait_condition = SELECT COUNT(*) = 301 from cardtest_tbl;
+--source include/wait_condition.inc
+
+ANALYZE TABLE cardtest_tbl;
+
--let $wait_condition = SELECT table_rows = 301 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl';
--source include/wait_condition.inc
-select count(*) from cardtest_tbl;
+SELECT COUNT(*) AS EXPECT_301 FROM cardtest_tbl;
let $cardinality1 = `SELECT cardinality from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl'`;
let $table_rows1 = `SELECT table_rows from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`;
@@ -56,14 +61,21 @@ let $avg_row_length1 = `SELECT avg_row_length from information_schema.tables WHE
let $data_length1 = `SELECT data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`;
--connection node_2
-set session wsrep_sync_wait=15;
use cardtest02;
--let $wait_timeout=600
+--let $wait_condition = SELECT COUNT(*) = 301 from cardtest_tbl;
+--source include/wait_condition.inc
+
+ANALYZE TABLE cardtest_tbl;
+
+--source include/wait_condition.inc
--let $wait_condition = SELECT table_rows = 301 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl';
--source include/wait_condition.inc
+--let $wait_condition = SELECT cardinality = 301 from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl';
+--source include/wait_condition.inc
-select count(*) from cardtest_tbl;
+SELECT COUNT(*) AS EXPECT_301 FROM cardtest_tbl;
if (`SELECT cardinality <> $cardinality1 from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl'`)
{
diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.cnf b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.cnf
new file mode 100644
index 00000000000..a09efd2e011
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.cnf
@@ -0,0 +1,15 @@
+!include ../galera_2nodes.cnf
+
+[mysqld]
+wsrep_sst_method=mariabackup
+wsrep_sst_auth="root:"
+
+[mysqld.1]
+wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'
+
+[mysqld.2]
+wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
+
+[sst]
+transferfmt=@ENV.MTR_GALERA_TFMT
+streamfmt=xbstream
diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test
new file mode 100644
index 00000000000..d1c30656139
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test
@@ -0,0 +1,71 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_mariabackup.inc
+
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
+
+--connection node_2
+
+#--connection node_2
+#--source suite/galera/include/galera_unload_provider.inc
+
+--echo Shutting down server ...
+--source include/shutdown_mysqld.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+CREATE DATABASE `lost+found`;
+USE `lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `lost+found`.t1;
+
+CREATE DATABASE `#mysql50#not_lost+found`;
+USE `#mysql50#not_lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `#mysql50#not_lost+found`.t1;
+
+#
+# Force SST
+#
+--echo Cleaning var directory ...
+--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
+--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr
+--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema
+--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test
+--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mysql
+--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data
+
+--connection node_2
+
+--echo Starting server ...
+let $restart_noprint=2;
+--source include/start_mysqld.inc
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+SELECT * FROM `lost+found`.t1;
+SELECT * FROM `#mysql50#not_lost+found`.t1;
+
+--connection node_1
+
+DROP DATABASE `lost+found`;
+DROP DATABASE `#mysql50#not_lost+found`;
+
+# rmdir $MYSQLD_DATADIR/lost+found;
+# rmdir $MYSQLD_DATADIR/not_lost+found;
+
+# Restore original auto_increment_offset values.
+--source include/auto_increment_offset_restore.inc
+
+--source include/galera_end.inc
diff --git a/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test b/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test
index 90c786f0af0..adb5cb04273 100644
--- a/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test
+++ b/mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test
@@ -142,8 +142,88 @@ INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
DROP TABLE t1;
+#
+# Test prepared staments
+#
+--connection node_1
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+
+PREPARE upd from 'update t1 set b = 100 where id = 5';
+PREPARE ins from 'insert into t1 values (11,11)';
+PREPARE del from 'delete from t1 where id = 4';
+PREPARE rep from 'replace into t1 values (12,12),(6,600)';
+
+EXECUTE upd;
+EXECUTE ins;
+EXECUTE del;
+EXECUTE rep;
+
+SELECT * FROM t1 ORDER BY id;
+
+--connection node_2
+SELECT * FROM t1 ORDER BY id;
+
+DROP TABLE t1;
+
+#
+# Test procedure
+#
+--connection node_1
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+
+DELIMITER |;
+CREATE PROCEDURE proc()
+BEGIN
+ UPDATE t1 set b = 100 WHERE id = 5;
+ INSERT INTO t1 VALUES (11,11);
+ DELETE FROM t1 WHERE id = 4;
+ REPLACE INTO t1 VALUES (12,12),(6,600);
+ COMMIT;
+END|
+DELIMITER ;|
+
+CALL proc();
+SELECT * FROM t1 ORDER BY id;
+
+--connection node_2
+SELECT * FROM t1 ORDER BY id;
+
+DROP PROCEDURE proc;
+DROP TABLE t1;
+
+#
+# Test trigger
+#
+--connection node_1
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, b INT) ENGINE=MyISAM;
+CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10);
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.b);
+CREATE TRIGGER tr2 BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, OLD.b),(NULL, NEW.b);
+CREATE TRIGGER tr3 BEFORE DELETE ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, OLD.b);
+
+INSERT INTO t1 VALUES (11,11);
+UPDATE t1 SET b = 200 WHERE id = 2;
+DELETE FROM t1 where id = 5;
+SELECT * FROM t1 ORDER BY id;
+SELECT * FROM t2 ORDER BY id;
+
+--connection node_2
+SELECT * FROM t1 ORDER BY id;
+SELECT * FROM t2 ORDER BY id;
+DROP TRIGGER tr1;
+DROP TRIGGER tr2;
+DROP TRIGGER tr3;
+DROP TABLE t1,t2;
+
--connection node_1
+--disable_query_log
--eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig
+--enable_query_log
--connection node_2
+--disable_query_log
--eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig
+--enable_query_log
diff --git a/mysql-test/suite/galera/t/galera_var_trx_fragment_size.test b/mysql-test/suite/galera/t/galera_var_trx_fragment_size.test
new file mode 100644
index 00000000000..f19152f37f1
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_var_trx_fragment_size.test
@@ -0,0 +1,43 @@
+--source include/galera_cluster.inc
+
+SET SESSION wsrep_trx_fragment_size=DEFAULT;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET SESSION wsrep_trx_fragment_size=0;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET GLOBAL wsrep_trx_fragment_size=DEFAULT;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET GLOBAL wsrep_trx_fragment_size=0;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET GLOBAL wsrep_trx_fragment_size=-1;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET SESSION wsrep_trx_fragment_size=-1;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET GLOBAL wsrep_trx_fragment_size=100;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET SESSION wsrep_trx_fragment_size=100;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+--error ER_WRONG_TYPE_FOR_VAR
+SET GLOBAL wsrep_trx_fragment_size='A';
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+--error ER_WRONG_TYPE_FOR_VAR
+SET SESSION wsrep_trx_fragment_size='A';
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+--error ER_WRONG_TYPE_FOR_VAR
+SET GLOBAL wsrep_trx_fragment_size=NULL;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+--error ER_WRONG_TYPE_FOR_VAR
+SET SESSION wsrep_trx_fragment_size=NULL;
+SHOW SESSION VARIABLES LIKE 'wsrep_trx_fragment_size';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_trx_fragment_size';
+SET GLOBAL wsrep_trx_fragment_size=DEFAULT;
diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def
index 0e2706f2dc3..425ad59c6b3 100644
--- a/mysql-test/suite/galera_3nodes/disabled.def
+++ b/mysql-test/suite/galera_3nodes/disabled.def
@@ -10,7 +10,9 @@
#
##############################################################################
+GCF-354 : MDEV-24010 galera_3nodes.GCF-354 MTR fails : WSREP has not yet prepared node for application use
galera_gtid_2_cluster : MDEV-23775 Galera test failure on galera_3nodes.galera_gtid_2_cluster
galera_ist_gcache_rollover : MDEV-23578 WSREP: exception caused by message: {v=0,t=1,ut=255,o=4,s=0,sr=0,as=1,f=6,src=50524cfe,srcvid=view_id(REG,50524cfe,4),insvid=view_id(UNKNOWN,00000000,0),ru=00000000,r=[-1,-1],fs=75,nl=(}
galera_slave_options_do :MDEV-8798
galera_slave_options_ignore : MDEV-8798
+galera_ipv6_mysqldump : MDEV-23576
diff --git a/mysql-test/suite/galera_3nodes/r/galera_parallel_apply_3nodes.result b/mysql-test/suite/galera_3nodes/r/galera_parallel_apply_3nodes.result
index 8211fb8501e..2acfe56bede 100644
--- a/mysql-test/suite/galera_3nodes/r/galera_parallel_apply_3nodes.result
+++ b/mysql-test/suite/galera_3nodes/r/galera_parallel_apply_3nodes.result
@@ -9,10 +9,16 @@ UPDATE t1 SET f1 = f1 + 10;;
connection node_2;
UPDATE t1 SET f1 = f1 + 100;;
connection node_1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1
connection node_2;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1
connection node_3;
-SELECT f1 = 111 FROM t1;
-f1 = 111
+SELECT COUNT(*) FROM t1;
+COUNT(*)
1
SELECT COUNT(*) IN (1, 2) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%committed%';
COUNT(*) IN (1, 2)
diff --git a/mysql-test/suite/galera_3nodes/t/galera_parallel_apply_3nodes.test b/mysql-test/suite/galera_3nodes/t/galera_parallel_apply_3nodes.test
index 659df2b3c93..f1168e59193 100644
--- a/mysql-test/suite/galera_3nodes/t/galera_parallel_apply_3nodes.test
+++ b/mysql-test/suite/galera_3nodes/t/galera_parallel_apply_3nodes.test
@@ -24,13 +24,25 @@ SET GLOBAL wsrep_slave_threads = 2;
--send UPDATE t1 SET f1 = f1 + 100;
--connection node_1
+#
+# Note that test is not deterministic. We have following cases possible
+# (1) Both updates are certified locally and then executed by the applier
+# (2) Certification of update in node_1 fails because applier has started
+# update from node_2
+# (3) Certification of update in node_2 fails because applier has started
+# update from node_1
+#
+--error 0,ER_LOCK_DEADLOCK
--reap
+SELECT COUNT(*) FROM t1;
--connection node_2
+--error 0,ER_LOCK_DEADLOCK
--reap
+SELECT COUNT(*) FROM t1;
--connection node_3
-SELECT f1 = 111 FROM t1;
+SELECT COUNT(*) FROM t1;
SELECT COUNT(*) IN (1, 2) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%committed%';
--eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_threads_orig;
diff --git a/mysql-test/suite/galera_sr/r/MDEV-23623.result b/mysql-test/suite/galera_sr/r/MDEV-23623.result
new file mode 100644
index 00000000000..edba2a16bcb
--- /dev/null
+++ b/mysql-test/suite/galera_sr/r/MDEV-23623.result
@@ -0,0 +1,26 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(255)) ENGINE=InnoDB;
+INSERT INTO t1 (f2) VALUES ('a');
+INSERT INTO t1 (f2) VALUES ('b');
+INSERT INTO t1 (f2) VALUES ('c');
+connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+connection node_2a;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_certify_apply_monitor_enter';
+connection node_2;
+SET SESSION wsrep_retry_autocommit = 0;
+SET SESSION wsrep_trx_fragment_size = 64;
+DELETE FROM t1 ORDER BY f1 DESC LIMIT 2;;
+connection node_2a;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+connection node_1;
+INSERT INTO t1 (f2) VALUES ('d'),('e');
+connection node_2a;
+SET GLOBAL wsrep_provider_options = 'signal=after_certify_apply_monitor_enter';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+connection node_2;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+connection node_1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera_sr/t/MDEV-23623.test b/mysql-test/suite/galera_sr/t/MDEV-23623.test
new file mode 100644
index 00000000000..2fe728f42bb
--- /dev/null
+++ b/mysql-test/suite/galera_sr/t/MDEV-23623.test
@@ -0,0 +1,50 @@
+#
+# MDEV-23623 - trans_commit_stmt(THD*): Assertion
+# `thd->in_active_multi_stmt_transaction() ||
+# thd->m_transaction_psi == __null' failed
+#
+
+--source include/galera_cluster.inc
+--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(255)) ENGINE=InnoDB;
+INSERT INTO t1 (f2) VALUES ('a');
+INSERT INTO t1 (f2) VALUES ('b');
+INSERT INTO t1 (f2) VALUES ('c');
+
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--connection node_2a
+SET SESSION wsrep_sync_wait = 0;
+--let $galera_sync_point = after_certify_apply_monitor_enter
+--source include/galera_set_sync_point.inc
+
+--connection node_2
+SET SESSION wsrep_retry_autocommit = 0;
+SET SESSION wsrep_trx_fragment_size = 64;
+--send DELETE FROM t1 ORDER BY f1 DESC LIMIT 2;
+
+--connection node_2a
+--source include/galera_wait_sync_point.inc
+
+#
+# This is going to cause a certification
+# failure on node_2
+#
+--connection node_1
+INSERT INTO t1 (f2) VALUES ('d'),('e');
+
+--connection node_2a
+--source include/galera_signal_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--connection node_2
+--error ER_LOCK_DEADLOCK
+--reap
+
+#
+# Assertion would happen when the following
+# DROP TABLE is applied on node_2
+#
+--connection node_1
+DROP TABLE t1;
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result
index a3cdacb67a2..50685e04a69 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result
@@ -769,3 +769,24 @@ ID ParentID Value Flag
INSERT INTO parent (ID) VALUES (100);
UPDATE child SET ParentID=100 WHERE ID=123123;
DROP TABLE child, parent;
+#
+# MDEV-23387 dict_load_foreign() fails to load the table during alter
+#
+SET FOREIGN_KEY_CHECKS=0;
+CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
+f3 INT AS (f1) VIRTUAL,
+INDEX(f1), INDEX(f2))ENGINE=InnoDB;
+ALTER TABLE t1 ADD CONSTRAINT r FOREIGN KEY(f2) REFERENCES t1(f1), LOCK=NONE;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) NOT NULL,
+ `f3` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL,
+ KEY `f1` (`f1`),
+ KEY `f2` (`f2`),
+ CONSTRAINT `r` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 DROP INDEX f1;
+ALTER TABLE t1 DROP f3;
+DROP TABLE t1;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test
index 226bacabaef..23d3ee97290 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test
@@ -637,3 +637,15 @@ UPDATE child SET ParentID=100 WHERE ID=123123;
# Cleanup
DROP TABLE child, parent;
+--echo #
+--echo # MDEV-23387 dict_load_foreign() fails to load the table during alter
+--echo #
+SET FOREIGN_KEY_CHECKS=0;
+CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
+ f3 INT AS (f1) VIRTUAL,
+ INDEX(f1), INDEX(f2))ENGINE=InnoDB;
+ALTER TABLE t1 ADD CONSTRAINT r FOREIGN KEY(f2) REFERENCES t1(f1), LOCK=NONE;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP INDEX f1;
+ALTER TABLE t1 DROP f3;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/include/wait_all_purged.inc b/mysql-test/suite/innodb/include/wait_all_purged.inc
index a478cc8aa2c..e3a506c7622 100644
--- a/mysql-test/suite/innodb/include/wait_all_purged.inc
+++ b/mysql-test/suite/innodb/include/wait_all_purged.inc
@@ -1,30 +1,17 @@
# Wait for everything to be purged.
# The user should have set innodb_purge_rseg_truncate_frequency=1.
+--disable_query_log
if (!$wait_all_purged)
{
- let $wait_all_purged= 0;
+ SET GLOBAL innodb_max_purge_lag_wait= 0;
}
-let $remaining_expect= `select concat('InnoDB ',$wait_all_purged)`;
-
-let $wait_counter= 600;
-if ($VALGRIND_TEST)
+if ($wait_all_purged)
{
- let $wait_counter= 2000;
+ eval SET GLOBAL innodb_max_purge_lag_wait= $wait_all_purged;
}
+--enable_query_log
-while ($wait_counter)
-{
- --replace_regex /.*History list length ([0-9]+).*/\1/
- let $remaining= `SHOW ENGINE INNODB STATUS`;
- if ($remaining == $remaining_expect)
- {
- let $wait_counter= 0;
- }
- if ($wait_counter)
- {
- real_sleep 0.1;
- dec $wait_counter;
- }
-}
+--replace_regex /.*History list length ([0-9]+).*/\1/
+let $remaining= `SHOW ENGINE INNODB STATUS`;
echo $remaining transactions not purged;
diff --git a/mysql-test/suite/innodb/r/flush.result b/mysql-test/suite/innodb/r/flush.result
new file mode 100644
index 00000000000..cd6bec48d4e
--- /dev/null
+++ b/mysql-test/suite/innodb/r/flush.result
@@ -0,0 +1,16 @@
+SELECT @@GLOBAL.innodb_open_files;
+@@GLOBAL.innodb_open_files
+10
+CREATE TABLE t0 (a INT) ENGINE=InnoDB;
+FLUSH TABLE t0 WITH READ LOCK;
+UNLOCK TABLES;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT) ENGINE=InnoDB;
+CREATE TABLE t4 (a INT) ENGINE=InnoDB;
+CREATE TABLE t5 (a INT) ENGINE=InnoDB;
+CREATE TABLE t6 (a INT) ENGINE=InnoDB;
+CREATE TABLE t7 (a INT) ENGINE=InnoDB;
+FLUSH TABLE t0 WITH READ LOCK;
+UNLOCK TABLES;
+DROP TABLE t0, t1, t2, t3, t4, t5, t6, t7;
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index aadfc338501..cd8b2d82a06 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -402,6 +402,55 @@ Opened_table_definitions 5
Opened_tables 5
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
+connect con1,localhost,root,,test;
+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
+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;
+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;
# Start of 10.2 tests
#
# MDEV-13246 Stale rows despite ON DELETE CASCADE constraint
@@ -751,6 +800,19 @@ DROP TABLE t1;
CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)),
FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
+#
+# MDEV-23675 Assertion `pos < table->n_def' in dict_table_get_nth_col
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a INT, b INT, c INT, KEY(c),
+FOREIGN KEY fx (b) REFERENCES t1 (c))
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,0,10,10);
+ALTER TABLE t1 DROP a, ALGORITHM=INSTANT;
+SET FOREIGN_KEY_CHECKS= 0;
+DROP INDEX fx ON t1;
+INSERT INTO t1 VALUES (2,11,11);
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=DEFAULT;
# End of 10.4 tests
#
# MDEV-20729 Fix REFERENCES constraint in column definition
diff --git a/mysql-test/suite/innodb/r/ibuf_not_empty.result b/mysql-test/suite/innodb/r/ibuf_not_empty.result
index 3382c74174e..d1b8203b063 100644
--- a/mysql-test/suite/innodb/r/ibuf_not_empty.result
+++ b/mysql-test/suite/innodb/r/ibuf_not_empty.result
@@ -1,4 +1,3 @@
-SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(
a INT AUTO_INCREMENT PRIMARY KEY,
b CHAR(1),
@@ -6,26 +5,11 @@ c INT,
INDEX(b))
ENGINE=InnoDB STATS_PERSISTENT=0;
SET GLOBAL innodb_change_buffering_debug = 1;
-BEGIN;
-INSERT INTO t1 VALUES(0,'x',1);
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-COMMIT;
-InnoDB 0 transactions not purged
+INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024;
# restart: --innodb-force-recovery=6 --innodb-change-buffer-dump
check table t1;
Table Op Msg_type Msg_text
-test.t1 check Warning InnoDB: Index 'b' contains #### entries, should be 4096.
+test.t1 check Warning InnoDB: Index 'b' contains 990 entries, should be 1024.
test.t1 check error Corrupt
# restart
SET GLOBAL innodb_fast_shutdown=0;
diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result
index 4bd1a09dd73..59abdb01d82 100644
--- a/mysql-test/suite/innodb/r/innodb-alter.result
+++ b/mysql-test/suite/innodb/r/innodb-alter.result
@@ -738,7 +738,7 @@ Table Create Table
t2 CREATE TABLE `t2` (
`C2` int(11) DEFAULT NULL,
KEY `c2` (`C2`),
- CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c2`) REFERENCES `t1` (`c1`)
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`C2`) REFERENCES `t1` (`C1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE t1 CHANGE COLUMN C1 c5 INT;
ALTER TABLE t2 CHANGE COLUMN C2 c6 INT;
@@ -785,7 +785,7 @@ SELECT C.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS C INNER JOIN
INFORMATION_SCHEMA.INNODB_SYS_TABLES T ON C.TABLE_ID=T.TABLE_ID
WHERE T.NAME='test/t1';
NAME
-a
+A
b
DROP TABLE t1;
# different FOREIGN KEY cases
@@ -842,27 +842,27 @@ t2 CREATE TABLE `t2` (
KEY `bb` (`BB`),
KEY `CC` (`CC`),
KEY `DD` (`DD`),
- CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`),
- CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`bb`) REFERENCES `t1` (`b`),
- CONSTRAINT `t2_ibfk_3` FOREIGN KEY (`cc`) REFERENCES `t1` (`c`),
- CONSTRAINT `t2_ibfk_4` FOREIGN KEY (`dd`) REFERENCES `t1` (`d`)
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`),
+ CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`BB`) REFERENCES `t1` (`B`),
+ CONSTRAINT `t2_ibfk_3` FOREIGN KEY (`CC`) REFERENCES `t1` (`C`),
+ CONSTRAINT `t2_ibfk_4` FOREIGN KEY (`DD`) REFERENCES `t1` (`D`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DELETE FROM t1 WHERE a=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE A=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE b=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE B=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE c=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE C=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE d=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DELETE FROM t1 WHERE D=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`aa`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`AA`) REFERENCES `t1` (`A`))
DROP TABLE t2, t1;
# virtual columns case too
CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a) VIRTUAL) ENGINE = InnoDB;
@@ -877,7 +877,7 @@ SELECT C.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS C INNER JOIN
INFORMATION_SCHEMA.INNODB_SYS_TABLES T ON C.TABLE_ID=T.TABLE_ID
WHERE T.NAME='test/t1';
NAME
-a
+A
b
DROP TABLE t1;
# and an MDEV-18041 regression related to indexes prefixes
diff --git a/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result b/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result
index d795b516d5e..678c8c67be5 100644
--- a/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result
+++ b/mysql-test/suite/innodb/r/innodb-change-buffer-recovery.result
@@ -50,5 +50,5 @@ Table Op Msg_type Msg_text
test.t1 check status OK
SHOW ENGINE INNODB STATUS;
Type Name Status
-InnoDB insert 79, delete mark 1
+InnoDB
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result
index 4b2df7eb287..484c9b30bd6 100644
--- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result
+++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result
@@ -34,7 +34,7 @@ grad_degree CREATE TABLE `grad_degree` (
`plan` varchar(10) NOT NULL,
`admit_term` char(4) NOT NULL,
`wdraw_rsn` varchar(4) NOT NULL DEFAULT '',
- `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed' else 'Not Completed' end) VIRTUAL,
+ `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed' else 'Not Completed' end) VIRTUAL,
`deg_start_term` char(4) NOT NULL DEFAULT '' COMMENT 'Educated guess at the beginning of the data',
`deg_as_of_term` char(4) NOT NULL COMMENT 'In most cases also end term',
PRIMARY KEY (`student_id`,`plan`,`admit_term`)
@@ -142,14 +142,14 @@ grad_degree CREATE TABLE `grad_degree` (
`plan` varchar(10) NOT NULL,
`admit_term` char(4) NOT NULL,
`wdraw_rsn` varchar(4) NOT NULL DEFAULT '',
- `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed' else 'Not Completed' end) VIRTUAL,
- `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed2' else 'Not Completed2' end) VIRTUAL,
- `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed3' else 'Not Completed3' end) VIRTUAL,
- `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed4' else 'Not Completed4' end) VIRTUAL,
- `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed5' else 'Not Completed5' end) VIRTUAL,
- `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed6' else 'Not Completed6' end) VIRTUAL,
- `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed7' else 'Not Completed7' end) VIRTUAL,
- `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed8' else 'Not Completed8' end) VIRTUAL,
+ `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed' else 'Not Completed' end) VIRTUAL,
+ `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed2' else 'Not Completed2' end) VIRTUAL,
+ `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed3' else 'Not Completed3' end) VIRTUAL,
+ `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed4' else 'Not Completed4' end) VIRTUAL,
+ `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed5' else 'Not Completed5' end) VIRTUAL,
+ `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed6' else 'Not Completed6' end) VIRTUAL,
+ `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed7' else 'Not Completed7' end) VIRTUAL,
+ `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed8' else 'Not Completed8' end) VIRTUAL,
`deg_start_term` char(4) NOT NULL DEFAULT '' COMMENT 'Educated guess at the beginning of the data',
`deg_as_of_term` char(4) NOT NULL COMMENT 'In most cases also end term',
PRIMARY KEY (`student_id`,`plan`,`admit_term`)
@@ -199,14 +199,14 @@ grad_degree CREATE TABLE `grad_degree` (
`plan` varchar(10) NOT NULL,
`admit_term` char(4) NOT NULL,
`wdraw_rsn` varchar(4) NOT NULL DEFAULT '',
- `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed' else 'Not Completed' end) VIRTUAL,
- `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed2' else 'Not Completed2' end) VIRTUAL,
- `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed3' else 'Not Completed3' end) VIRTUAL,
- `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed4' else 'Not Completed4' end) VIRTUAL,
- `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed5' else 'Not Completed5' end) VIRTUAL,
- `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed6' else 'Not Completed6' end) VIRTUAL,
- `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed7' else 'Not Completed7' end) VIRTUAL,
- `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed8' else 'Not Completed8' end) VIRTUAL,
+ `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed' else 'Not Completed' end) VIRTUAL,
+ `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed2' else 'Not Completed2' end) VIRTUAL,
+ `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed3' else 'Not Completed3' end) VIRTUAL,
+ `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed4' else 'Not Completed4' end) VIRTUAL,
+ `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed5' else 'Not Completed5' end) VIRTUAL,
+ `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed6' else 'Not Completed6' end) VIRTUAL,
+ `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed7' else 'Not Completed7' end) VIRTUAL,
+ `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed8' else 'Not Completed8' end) VIRTUAL,
`deg_as_of_term` char(4) NOT NULL COMMENT 'In most cases also end term',
PRIMARY KEY (`student_id`,`plan`,`admit_term`),
KEY `grad_degree_as_of_term_ndx` (`deg_as_of_term`)
@@ -278,14 +278,14 @@ grad_degree CREATE TABLE `grad_degree` (
`plan` varchar(10) NOT NULL,
`admit_term` char(4) NOT NULL,
`wdraw_rsn` varchar(4) NOT NULL DEFAULT '',
- `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed' else 'Not Completed' end) VIRTUAL,
- `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed2' else 'Not Completed2' end) VIRTUAL,
- `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed3' else 'Not Completed3' end) VIRTUAL,
- `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed4' else 'Not Completed4' end) VIRTUAL,
- `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed5' else 'Not Completed5' end) VIRTUAL,
- `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed6' else 'Not Completed6' end) VIRTUAL,
- `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed7' else 'Not Completed7' end) VIRTUAL,
- `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when (`wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC') then 'Completed8' else 'Not Completed8' end) VIRTUAL,
+ `ofis_deg_status` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed' else 'Not Completed' end) VIRTUAL,
+ `ofis_deg_status2` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress2' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed2' else 'Not Completed2' end) VIRTUAL,
+ `ofis_deg_status3` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress3' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed3' else 'Not Completed3' end) VIRTUAL,
+ `ofis_deg_status4` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress4' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed4' else 'Not Completed4' end) VIRTUAL,
+ `ofis_deg_status5` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress5' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed5' else 'Not Completed5' end) VIRTUAL,
+ `ofis_deg_status6` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress6' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed6' else 'Not Completed6' end) VIRTUAL,
+ `ofis_deg_status7` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress7' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed7' else 'Not Completed7' end) VIRTUAL,
+ `ofis_deg_status8` varchar(15) GENERATED ALWAYS AS (case when `wdraw_rsn` = '' then 'In progress8' when `wdraw_rsn` = 'DCMP' or `wdraw_rsn` = 'TRDC' then 'Completed8' else 'Not Completed8' end) VIRTUAL,
`deg_start_term` char(4) NOT NULL DEFAULT '' COMMENT 'Educated guess at the beginning of the data',
`deg_as_of_term` char(4) NOT NULL COMMENT 'In most cases also end term',
PRIMARY KEY (`student_id`,`plan`,`admit_term`)
diff --git a/mysql-test/suite/innodb/r/innodb_scrub.result b/mysql-test/suite/innodb/r/innodb_scrub.result
index f783b9f167c..1a4db0b541e 100644
--- a/mysql-test/suite/innodb/r/innodb_scrub.result
+++ b/mysql-test/suite/innodb/r/innodb_scrub.result
@@ -6,5 +6,7 @@ UNLOCK TABLES;
FOUND 500500 /unicycle|repairman/ in t1.ibd
DELETE FROM t1;
InnoDB 0 transactions not purged
+FLUSH TABLE t1 FOR EXPORT;
+UNLOCK TABLES;
NOT FOUND /unicycle|repairman/ in t1.ibd
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result
index 9ab72408274..775bbc017a1 100644
--- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result
+++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result
@@ -89,16 +89,8 @@ buffer_flush_neighbor buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NU
buffer_flush_neighbor_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages queued as a neighbor batch
buffer_flush_n_to_flush_requested buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages requested for flushing.
buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages target by LSN Age for flushing.
-buffer_flush_adaptive_avg_time_slot buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently per slot.
-buffer_LRU_batch_flush_avg_time_slot buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for LRU batch flushing recently per slot.
-buffer_flush_adaptive_avg_time_thread buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently per thread.
-buffer_LRU_batch_flush_avg_time_thread buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for LRU batch flushing recently per thread.
-buffer_flush_adaptive_avg_time_est buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Estimated time (ms) spent for adaptive flushing recently.
-buffer_LRU_batch_flush_avg_time_est buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Estimated time (ms) spent for LRU batch flushing recently.
-buffer_flush_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for flushing recently.
+buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently.
buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period.
-buffer_LRU_batch_flush_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of LRU batch flushes passed during the recent Avg period.
-buffer_flush_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of flushes passed during the recent Avg period.
buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free.
buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free.
buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening
@@ -124,9 +116,6 @@ buffer_LRU_batch_flush_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL
buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages evicted as part of LRU batches
buffer_LRU_batches_evict buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of LRU batches
buffer_LRU_batch_evict_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages queued as an LRU batch
-buffer_LRU_single_flush_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of single page LRU flush
-buffer_LRU_single_flush_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times single page LRU flush is called
-buffer_LRU_single_flush_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Page scanned per single LRU flush
buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed
buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page
buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search
@@ -201,7 +190,6 @@ log_lsn_current recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0
log_lsn_checkpoint_age recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Current LSN value minus LSN at last checkpoint
log_lsn_buf_pool_oldest recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value The oldest modified block LSN in the buffer pool
log_max_modified_age_async recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Maximum LSN difference; when exceeded, start asynchronous preflush
-log_max_modified_age_sync recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Maximum LSN difference; when exceeded, start synchronous preflush
log_pending_log_flushes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending log flushes
log_pending_checkpoint_writes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending checkpoints
log_num_log_io recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of log I/Os
@@ -252,7 +240,6 @@ innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NU
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
innodb_dict_lru_count_idle server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the idle loop
-innodb_checkpoint_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent by master thread to do checkpoint
innodb_dblwr_writes server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of doublewrite operations that have been performed (innodb_dblwr_writes)
innodb_dblwr_pages_written server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of pages that have been written for doublewrite operations (innodb_dblwr_pages_written)
innodb_page_size server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value InnoDB page size in bytes (innodb_page_size)
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 fc0a590934a..3ae06c48ecb 100644
--- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
+++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
@@ -48,3 +48,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/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result
index 1dfc709a775..02376a3cc79 100644
--- a/mysql-test/suite/innodb/r/instant_alter_bugs.result
+++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result
@@ -416,4 +416,27 @@ DROP TABLE t;
CREATE TABLE t (pk SERIAL, b TEXT CHARACTER SET utf8) ENGINE=InnoDB;
ALTER TABLE t MODIFY b TEXT CHARACTER SET utf8mb4 FIRST;
DROP TABLE t;
+#
+# MDEV-23672 Assertion `v.v_indexes.empty()' failed in dict_table_t::instant_column
+#
+create table t1 (
+col_int integer,
+col_text text not null,
+col_int_g integer generated always as (col_int) unique,
+col_text_g text generated always as (substr(col_text,1,499)) )
+engine innodb row_format = redundant;
+insert into t1 (col_int,col_text) values (0, 'a'), (null, 'b');
+alter table t1 modify column col_text text null, algorithm = instant;
+insert into t1 (col_int,col_text) values (1, null), (null, null);
+update t1 set col_text= 'd';
+select * from t1;
+col_int col_text col_int_g col_text_g
+0 d 0 d
+NULL d NULL d
+1 d 1 d
+NULL d NULL d
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/mysql-test/suite/innodb/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result
index cfcb24f8bb2..ef0e310492a 100644
--- a/mysql-test/suite/innodb/r/instant_alter_crash.result
+++ b/mysql-test/suite/innodb/r/instant_alter_crash.result
@@ -40,6 +40,7 @@ ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
+SET debug_dbug='+d,dict_sys_mutex_avoid';
UPDATE t1 SET c2=c2+1;
# Kill the server
disconnect ddl;
@@ -68,6 +69,7 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum');
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
+SET debug_dbug='+d,dict_sys_mutex_avoid';
DELETE FROM t1;
# Kill the server
disconnect ddl;
diff --git a/mysql-test/suite/innodb/r/instant_alter_index_rename.result b/mysql-test/suite/innodb/r/instant_alter_index_rename.result
index 69f7cc8df4c..41dec275d90 100644
--- a/mysql-test/suite/innodb/r/instant_alter_index_rename.result
+++ b/mysql-test/suite/innodb/r/instant_alter_index_rename.result
@@ -198,3 +198,39 @@ Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
DROP FUNCTION get_index_id;
+#
+# MDEV-23356 InnoDB: Failing assertion: field->col->mtype == type, crash or ASAN failures in row_sel_convert_mysql_key_to_innobase, InnoDB indexes are inconsistent after INDEX changes
+#
+CREATE TABLE t1 (a INT, b INT, c CHAR(8),
+KEY ind1(c), KEY ind2(b)) ENGINE=InnoDB STATS_PERSISTENT=1;
+INSERT INTO t1 SELECT 1, 1, 'a' FROM seq_1_to_100;
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
+table_name index_name stat_name
+t1 GEN_CLUST_INDEX n_diff_pfx01
+t1 GEN_CLUST_INDEX n_leaf_pages
+t1 GEN_CLUST_INDEX size
+t1 ind1 n_diff_pfx01
+t1 ind1 n_diff_pfx02
+t1 ind1 n_leaf_pages
+t1 ind1 size
+t1 ind2 n_diff_pfx01
+t1 ind2 n_diff_pfx02
+t1 ind2 n_leaf_pages
+t1 ind2 size
+ALTER TABLE t1 DROP INDEX ind2, ADD INDEX ind3(b),
+DROP INDEX ind1, ADD INDEX ind2(c);
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
+table_name index_name stat_name
+t1 GEN_CLUST_INDEX n_diff_pfx01
+t1 GEN_CLUST_INDEX n_leaf_pages
+t1 GEN_CLUST_INDEX size
+t1 ind2 n_diff_pfx01
+t1 ind2 n_diff_pfx02
+t1 ind2 n_leaf_pages
+t1 ind2 size
+t1 ind3 n_diff_pfx01
+t1 ind3 n_diff_pfx02
+t1 ind3 n_leaf_pages
+t1 ind3 size
+UPDATE t1 SET a = 1 WHERE c = 'foo';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff b/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff
index 53d2be18f9c..8722b724c6e 100644
--- a/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff
+++ b/mysql-test/suite/innodb/r/instant_alter_purge,release.rdiff
@@ -1,6 +1,6 @@
--- instant_alter_purge.result
+++ instant_alter_purge,release.result
-@@ -32,15 +32,11 @@
+@@ -32,16 +32,11 @@
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1;
@@ -9,7 +9,8 @@
connection purge_control;
-SET DEBUG_SYNC='now WAIT_FOR go';
COMMIT;
- InnoDB 0 transactions not purged
+ SET GLOBAL innodb_max_purge_lag_wait= 0;
+-InnoDB 0 transactions not purged
-SET DEBUG_SYNC='now SIGNAL do';
disconnect purge_control;
connection default;
diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result
index 0c0168fb266..7bdcf7acb45 100644
--- a/mysql-test/suite/innodb/r/monitor.result
+++ b/mysql-test/suite/innodb/r/monitor.result
@@ -55,16 +55,8 @@ buffer_flush_neighbor disabled
buffer_flush_neighbor_pages disabled
buffer_flush_n_to_flush_requested disabled
buffer_flush_n_to_flush_by_age disabled
-buffer_flush_adaptive_avg_time_slot disabled
-buffer_LRU_batch_flush_avg_time_slot disabled
-buffer_flush_adaptive_avg_time_thread disabled
-buffer_LRU_batch_flush_avg_time_thread disabled
-buffer_flush_adaptive_avg_time_est disabled
-buffer_LRU_batch_flush_avg_time_est disabled
-buffer_flush_avg_time disabled
+buffer_flush_adaptive_avg_time disabled
buffer_flush_adaptive_avg_pass disabled
-buffer_LRU_batch_flush_avg_pass disabled
-buffer_flush_avg_pass disabled
buffer_LRU_get_free_loops disabled
buffer_LRU_get_free_waits disabled
buffer_flush_avg_page_rate disabled
@@ -90,9 +82,6 @@ buffer_LRU_batch_flush_pages disabled
buffer_LRU_batch_evict_total_pages disabled
buffer_LRU_batches_evict disabled
buffer_LRU_batch_evict_pages disabled
-buffer_LRU_single_flush_scanned disabled
-buffer_LRU_single_flush_num_scan disabled
-buffer_LRU_single_flush_scanned_per_call disabled
buffer_LRU_single_flush_failure_count disabled
buffer_LRU_get_free_search disabled
buffer_LRU_search_scanned disabled
@@ -167,7 +156,6 @@ log_lsn_current disabled
log_lsn_checkpoint_age disabled
log_lsn_buf_pool_oldest disabled
log_max_modified_age_async disabled
-log_max_modified_age_sync disabled
log_pending_log_flushes disabled
log_pending_checkpoint_writes disabled
log_num_log_io disabled
@@ -218,7 +206,6 @@ innodb_log_flush_usec disabled
innodb_dict_lru_usec disabled
innodb_dict_lru_count_active disabled
innodb_dict_lru_count_idle disabled
-innodb_checkpoint_usec disabled
innodb_dblwr_writes disabled
innodb_dblwr_pages_written disabled
innodb_page_size disabled
diff --git a/mysql-test/suite/innodb/r/purge_secondary.result b/mysql-test/suite/innodb/r/purge_secondary.result
index 7c2b4151e76..a583e46418d 100644
--- a/mysql-test/suite/innodb/r/purge_secondary.result
+++ b/mysql-test/suite/innodb/r/purge_secondary.result
@@ -148,10 +148,6 @@ SELECT (variable_value > 0) FROM information_schema.global_status
WHERE LOWER(variable_name) LIKE 'INNODB_BUFFER_POOL_PAGES_FLUSHED';
(variable_value > 0)
1
-SELECT NAME, SUBSYSTEM FROM INFORMATION_SCHEMA.INNODB_METRICS
-WHERE NAME="buffer_LRU_batch_evict_total_pages" AND COUNT > 0;
-NAME SUBSYSTEM
-buffer_LRU_batch_evict_total_pages buffer
# Note: The OTHER_INDEX_SIZE does not cover any SPATIAL INDEX.
# To test that all indexes were emptied, replace DROP TABLE
# with the following, and examine the root pages in t1.ibd:
diff --git a/mysql-test/suite/innodb/r/redo_log_during_checkpoint.result b/mysql-test/suite/innodb/r/redo_log_during_checkpoint.result
index 3915b07f12e..c7b4bb4403b 100644
--- a/mysql-test/suite/innodb/r/redo_log_during_checkpoint.result
+++ b/mysql-test/suite/innodb/r/redo_log_during_checkpoint.result
@@ -10,6 +10,7 @@ set global innodb_log_checkpoint_now = 1;
ERROR HY000: Lost connection to MySQL server during query
# Skip MLOG_FILE_NAME redo records during recovery
DROP DATABASE very_long_database_name;
+SET GLOBAL innodb_flush_sync=OFF;
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
SET GLOBAL innodb_dict_stats_disabled_debug = 1;
SET GLOBAL innodb_master_thread_disabled_debug = 1;
diff --git a/mysql-test/suite/innodb/r/stats_persistent.result b/mysql-test/suite/innodb/r/stats_persistent.result
new file mode 100644
index 00000000000..3ae10e31cb3
--- /dev/null
+++ b/mysql-test/suite/innodb/r/stats_persistent.result
@@ -0,0 +1,19 @@
+#
+# MDEV-23991 dict_table_stats_lock() has unnecessarily long scope
+#
+CREATE TABLE t1(a INT) ENGINE=INNODB STATS_PERSISTENT=1;
+SET DEBUG_SYNC='dict_stats_update_persistent SIGNAL stop WAIT_FOR go';
+ANALYZE TABLE t1;
+connect con1, localhost, root;
+SET DEBUG_SYNC='now WAIT_FOR stop';
+SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE ENGINE='InnoDB';
+ENGINE SUM(DATA_LENGTH+INDEX_LENGTH) COUNT(ENGINE) SUM(DATA_LENGTH) SUM(INDEX_LENGTH)
+InnoDB 114688 4 65536 49152
+SET DEBUG_SYNC='now SIGNAL go';
+disconnect con1;
+connection default;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/table_definition_cache_debug.result b/mysql-test/suite/innodb/r/table_definition_cache_debug.result
index 2c2c6de44ae..df171c89cd4 100644
--- a/mysql-test/suite/innodb/r/table_definition_cache_debug.result
+++ b/mysql-test/suite/innodb/r/table_definition_cache_debug.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("InnoDB: innodb_open_files=13 is exceeded");
+call mtr.add_suppression("InnoDB: innodb_open_files=.* is exceeded");
SET @save_tdc= @@GLOBAL.table_definition_cache;
SET @save_toc= @@GLOBAL.table_open_cache;
SET GLOBAL table_definition_cache= 400;
diff --git a/mysql-test/suite/innodb/t/alter_large_dml.test b/mysql-test/suite/innodb/t/alter_large_dml.test
index 5ab3f394115..e44adf2c3ba 100644
--- a/mysql-test/suite/innodb/t/alter_large_dml.test
+++ b/mysql-test/suite/innodb/t/alter_large_dml.test
@@ -1,4 +1,6 @@
--source include/big_test.inc
+# debug sync points times out when using valgrind
+--source include/not_valgrind.inc
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
diff --git a/mysql-test/suite/innodb/t/flush.opt b/mysql-test/suite/innodb/t/flush.opt
new file mode 100644
index 00000000000..99dbd8f47c3
--- /dev/null
+++ b/mysql-test/suite/innodb/t/flush.opt
@@ -0,0 +1 @@
+--innodb-open-files=10
diff --git a/mysql-test/suite/innodb/t/flush.test b/mysql-test/suite/innodb/t/flush.test
new file mode 100644
index 00000000000..e03728825cf
--- /dev/null
+++ b/mysql-test/suite/innodb/t/flush.test
@@ -0,0 +1,19 @@
+--source include/have_innodb.inc
+
+SELECT @@GLOBAL.innodb_open_files;
+
+CREATE TABLE t0 (a INT) ENGINE=InnoDB;
+# Ensure that the created table t0 is clean.
+FLUSH TABLE t0 WITH READ LOCK;
+UNLOCK TABLES;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+CREATE TABLE t3 (a INT) ENGINE=InnoDB;
+CREATE TABLE t4 (a INT) ENGINE=InnoDB;
+CREATE TABLE t5 (a INT) ENGINE=InnoDB;
+CREATE TABLE t6 (a INT) ENGINE=InnoDB;
+CREATE TABLE t7 (a INT) ENGINE=InnoDB;
+# Now, the data file for t0 should not be open anymore.
+FLUSH TABLE t0 WITH READ LOCK;
+UNLOCK TABLES;
+DROP TABLE t0, t1, t2, t3, t4, t5, t6, t7;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index c1713cb9742..ebde222ee69 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -407,6 +407,55 @@ 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
#
@@ -741,6 +790,20 @@ DROP TABLE t1;
CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)),
FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB;
+--echo #
+--echo # MDEV-23675 Assertion `pos < table->n_def' in dict_table_get_nth_col
+--echo #
+CREATE TABLE t1 (pk int PRIMARY KEY, a INT, b INT, c INT, KEY(c),
+FOREIGN KEY fx (b) REFERENCES t1 (c))
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,0,10,10);
+ALTER TABLE t1 DROP a, ALGORITHM=INSTANT;
+SET FOREIGN_KEY_CHECKS= 0;
+DROP INDEX fx ON t1;
+INSERT INTO t1 VALUES (2,11,11);
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=DEFAULT;
+
-- echo # End of 10.4 tests
--echo #
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.combinations b/mysql-test/suite/innodb/t/ibuf_not_empty.combinations
index 729380593f3..c4b45dcca32 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.combinations
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.combinations
@@ -1,5 +1,9 @@
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
+--innodb-page-size=4k
+--innodb-force-recovery=2
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32
+--innodb-page-size=4k
+--innodb-force-recovery=2
diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test
index a3f4ad9ac5c..545a78c887e 100644
--- a/mysql-test/suite/innodb/t/ibuf_not_empty.test
+++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test
@@ -3,10 +3,8 @@
--source include/have_debug.inc
# Embedded server tests do not support restarting
--source include/not_embedded.inc
-# The test is not big enough to use change buffering with larger page size.
---source include/have_innodb_max_16k.inc
+--source include/have_sequence.inc
-SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
--disable_query_log
call mtr.add_suppression("InnoDB: Failed to find tablespace for table `test`\\.`t1` in the cache\\. Attempting to load the tablespace with space id");
call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for test.t1, old maximum was");
@@ -30,27 +28,10 @@ SET GLOBAL innodb_change_buffering_debug = 1;
# Create enough rows for the table, so that the change buffer will be
# used for modifying the secondary index page. There must be multiple
# index pages, because changes to the root page are never buffered.
-BEGIN;
-INSERT INTO t1 VALUES(0,'x',1);
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-INSERT INTO t1 SELECT 0,b,c FROM t1;
-COMMIT;
+INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024;
let MYSQLD_DATADIR=`select @@datadir`;
let PAGE_SIZE=`select @@innodb_page_size`;
-# Ensure that purge will not access the truncated .ibd file
---source include/wait_all_purged.inc
-
--source include/shutdown_mysqld.inc
# Corrupt the change buffer bitmap, to claim that pages are clean
@@ -87,7 +68,7 @@ EOF
--let $restart_parameters= --innodb-force-recovery=6 --innodb-change-buffer-dump
--source include/start_mysqld.inc
---replace_regex /contains \d+ entries/contains #### entries/
+--replace_regex /contains \d+ entries/contains 990 entries/
check table t1;
--source include/shutdown_mysqld.inc
diff --git a/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test b/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test
index 79d9cc814a0..a12ca43cec1 100644
--- a/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test
+++ b/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test
@@ -76,6 +76,6 @@ SET GLOBAL innodb_fast_shutdown=0;
--let $restart_parameters=
--source include/restart_mysqld.inc
CHECK TABLE t1;
-replace_regex /.*operations:.* (insert.*), delete \d.*discarded .*/\1/;
+replace_regex /.*operations:.* insert [1-9][0-9]*, delete mark [1-9][0-9]*, delete \d.*discarded .*//;
SHOW ENGINE INNODB STATUS;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-trim.test b/mysql-test/suite/innodb/t/innodb-trim.test
index 0f38ea5ba84..3f8eb5f2c71 100644
--- a/mysql-test/suite/innodb/t/innodb-trim.test
+++ b/mysql-test/suite/innodb/t/innodb-trim.test
@@ -32,18 +32,6 @@ commit;
set autocommit=1;
-let $success= `SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'innodb_num_page_compressed_trim_op'`;
-
-if (!$success) {
---disable_query_log
---disable_result_log
- DROP PROCEDURE innodb_insert_proc;
- DROP TABLE innodb_page_compressed;
---enable_query_log
---enable_result_log
- --skip "Test requires TRIM";
-}
-
DROP PROCEDURE innodb_insert_proc;
DROP TABLE innodb_page_compressed;
diff --git a/mysql-test/suite/innodb/t/innodb_bug30113362.test b/mysql-test/suite/innodb/t/innodb_bug30113362.test
index de5d07ffb29..789f1a493cb 100644
--- a/mysql-test/suite/innodb/t/innodb_bug30113362.test
+++ b/mysql-test/suite/innodb/t/innodb_bug30113362.test
@@ -6,6 +6,8 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_innodb_16k.inc
+# debug sync points times out when using valgrind
+--source include/not_valgrind.inc
--disable_query_log
SET @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug;
diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test
index c1b7fb4df1d..88b4e9cfd76 100644
--- a/mysql-test/suite/innodb/t/innodb_scrub.test
+++ b/mysql-test/suite/innodb/t/innodb_scrub.test
@@ -22,5 +22,7 @@ let SEARCH_FILE= $MYSQLD_DATADIR/test/t1.ibd;
-- source include/search_pattern_in_file.inc
DELETE FROM t1;
-- source include/wait_all_purged.inc
+FLUSH TABLE t1 FOR EXPORT;
+UNLOCK TABLES;
-- source include/search_pattern_in_file.inc
DROP TABLE t1;
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/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index 4548e978f86..ad4343a056d 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -437,4 +437,21 @@ CREATE TABLE t (pk SERIAL, b TEXT CHARACTER SET utf8) ENGINE=InnoDB;
ALTER TABLE t MODIFY b TEXT CHARACTER SET utf8mb4 FIRST;
DROP TABLE t;
+--echo #
+--echo # MDEV-23672 Assertion `v.v_indexes.empty()' failed in dict_table_t::instant_column
+--echo #
+create table t1 (
+ col_int integer,
+ col_text text not null,
+ col_int_g integer generated always as (col_int) unique,
+ col_text_g text generated always as (substr(col_text,1,499)) )
+engine innodb row_format = redundant;
+insert into t1 (col_int,col_text) values (0, 'a'), (null, 'b');
+alter table t1 modify column col_text text null, algorithm = instant;
+insert into t1 (col_int,col_text) values (1, null), (null, null);
+update t1 set col_text= 'd';
+select * from t1;
+check table t1;
+drop table t1;
+
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test
index 13ff292d9ff..f9b18aa589f 100644
--- a/mysql-test/suite/innodb/t/instant_alter_crash.test
+++ b/mysql-test/suite/innodb/t/instant_alter_crash.test
@@ -55,6 +55,7 @@ ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
+SET debug_dbug='+d,dict_sys_mutex_avoid';
UPDATE t1 SET c2=c2+1;
--source include/kill_mysqld.inc
@@ -83,6 +84,7 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum');
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
+SET debug_dbug='+d,dict_sys_mutex_avoid';
DELETE FROM t1;
--source include/kill_mysqld.inc
diff --git a/mysql-test/suite/innodb/t/instant_alter_index_rename.test b/mysql-test/suite/innodb/t/instant_alter_index_rename.test
index dd6cee7c860..af66c1027cc 100644
--- a/mysql-test/suite/innodb/t/instant_alter_index_rename.test
+++ b/mysql-test/suite/innodb/t/instant_alter_index_rename.test
@@ -1,5 +1,6 @@
--source include/have_innodb.inc
--source include/have_debug.inc
+--source include/have_sequence.inc
delimiter |;
create function get_index_id(tbl_id int, index_name char(100))
@@ -207,3 +208,22 @@ CHECK TABLE t1 EXTENDED ;
DROP TABLE t1;
DROP FUNCTION get_index_id;
+
+--echo #
+--echo # MDEV-23356 InnoDB: Failing assertion: field->col->mtype == type, crash or ASAN failures in row_sel_convert_mysql_key_to_innobase, InnoDB indexes are inconsistent after INDEX changes
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, c CHAR(8),
+ KEY ind1(c), KEY ind2(b)) ENGINE=InnoDB STATS_PERSISTENT=1;
+
+INSERT INTO t1 SELECT 1, 1, 'a' FROM seq_1_to_100;
+
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
+
+ALTER TABLE t1 DROP INDEX ind2, ADD INDEX ind3(b),
+ DROP INDEX ind1, ADD INDEX ind2(c);
+
+SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats;
+
+UPDATE t1 SET a = 1 WHERE c = 'foo';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test
index 34b4ce06f5f..f2c85ce10e7 100644
--- a/mysql-test/suite/innodb/t/purge_secondary.test
+++ b/mysql-test/suite/innodb/t/purge_secondary.test
@@ -131,9 +131,6 @@ ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
SELECT (variable_value > 0) FROM information_schema.global_status
WHERE LOWER(variable_name) LIKE 'INNODB_BUFFER_POOL_PAGES_FLUSHED';
-SELECT NAME, SUBSYSTEM FROM INFORMATION_SCHEMA.INNODB_METRICS
-WHERE NAME="buffer_LRU_batch_evict_total_pages" AND COUNT > 0;
-
--echo # Note: The OTHER_INDEX_SIZE does not cover any SPATIAL INDEX.
--echo # To test that all indexes were emptied, replace DROP TABLE
--echo # with the following, and examine the root pages in t1.ibd:
diff --git a/mysql-test/suite/innodb/t/redo_log_during_checkpoint.test b/mysql-test/suite/innodb/t/redo_log_during_checkpoint.test
index 645ae8c7855..85beb3ee1d2 100644
--- a/mysql-test/suite/innodb/t/redo_log_during_checkpoint.test
+++ b/mysql-test/suite/innodb/t/redo_log_during_checkpoint.test
@@ -44,6 +44,7 @@ set global innodb_log_checkpoint_now = 1;
DROP DATABASE very_long_database_name;
+SET GLOBAL innodb_flush_sync=OFF;
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
SET GLOBAL innodb_dict_stats_disabled_debug = 1;
SET GLOBAL innodb_master_thread_disabled_debug = 1;
diff --git a/mysql-test/suite/innodb/t/stats_persistent.test b/mysql-test/suite/innodb/t/stats_persistent.test
new file mode 100644
index 00000000000..ac412d56d0d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/stats_persistent.test
@@ -0,0 +1,27 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/count_sessions.inc
+
+--echo #
+--echo # MDEV-23991 dict_table_stats_lock() has unnecessarily long scope
+--echo #
+CREATE TABLE t1(a INT) ENGINE=INNODB STATS_PERSISTENT=1;
+
+SET DEBUG_SYNC='dict_stats_update_persistent SIGNAL stop WAIT_FOR go';
+--send ANALYZE TABLE t1
+
+--connect(con1, localhost, root)
+SET DEBUG_SYNC='now WAIT_FOR stop';
+
+SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE ENGINE='InnoDB';
+
+SET DEBUG_SYNC='now SIGNAL go';
+--disconnect con1
+
+--connection default
+--reap
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.test b/mysql-test/suite/innodb/t/table_definition_cache_debug.test
index 70467b53435..6a466af4cc5 100644
--- a/mysql-test/suite/innodb/t/table_definition_cache_debug.test
+++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.test
@@ -4,7 +4,7 @@
# This test is slow on buildbot.
--source include/big_test.inc
-call mtr.add_suppression("InnoDB: innodb_open_files=13 is exceeded");
+call mtr.add_suppression("InnoDB: innodb_open_files=.* is exceeded");
SET @save_tdc= @@GLOBAL.table_definition_cache;
SET @save_toc= @@GLOBAL.table_open_cache;
diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test
index 8e3ddf95634..389e106a345 100644
--- a/mysql-test/suite/innodb/t/temporary_table.test
+++ b/mysql-test/suite/innodb/t/temporary_table.test
@@ -131,7 +131,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
# We cannot use include/restart_mysqld.inc in this particular test,
# because SHOW STATUS would fail due to unwritable (nonexistent) tmpdir.
--source include/shutdown_mysqld.inc
---exec echo "restart: --tmpdir=/dev/null/nonexistent" > $_expect_file_name
+--exec echo "restart: --tmpdir=/dev/null/nonexistent --skip-innodb-fast-shutdown" > $_expect_file_name
--enable_reconnect
--disable_result_log
--disable_query_log
diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.test b/mysql-test/suite/innodb/t/undo_truncate_recover.test
index e6a873085e0..e499ff3dfbe 100644
--- a/mysql-test/suite/innodb/t/undo_truncate_recover.test
+++ b/mysql-test/suite/innodb/t/undo_truncate_recover.test
@@ -3,6 +3,7 @@
#
--source include/big_test.inc
+--source include/not_valgrind.inc
# With larger innodb_page_size, the undo log tablespaces do not grow enough.
--source include/innodb_page_size_small.inc
--source include/have_innodb.inc
diff --git a/mysql-test/suite/innodb_fts/r/basic.result b/mysql-test/suite/innodb_fts/r/basic.result
index d96127fbc34..b3fd94509c3 100644
--- a/mysql-test/suite/innodb_fts/r/basic.result
+++ b/mysql-test/suite/innodb_fts/r/basic.result
@@ -132,6 +132,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 431a95442e6..c192fced34e 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
@@ -919,4 +919,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/t/basic.test b/mysql-test/suite/innodb_fts/t/basic.test
index 0c0920c5f16..7a5c83ffb06 100644
--- a/mysql-test/suite/innodb_fts/t/basic.test
+++ b/mysql-test/suite/innodb_fts/t/basic.test
@@ -107,6 +107,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 3c794ec6440..46b65590298 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
@@ -889,4 +889,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/maria/alter.result b/mysql-test/suite/maria/alter.result
index 4e6f21b70a7..e1a57ed654f 100644
--- a/mysql-test/suite/maria/alter.result
+++ b/mysql-test/suite/maria/alter.result
@@ -104,3 +104,83 @@ DROP TABLE t1;
#
# End of 10.2 test
#
+#
+# MDEV-17665 Assertion `!share || share->page_type == PAGECACHE_LSN_PAGE',
+# `type != PAGECACHE_READ_UNKNOWN_PAGE' and similar ones upon concurrent
+# Aria operations
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=Aria;
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
+connect con1,localhost,root,,test;
+connect con2,localhost,root,,test;
+INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
+connection con1;
+FLUSH TABLES;
+connection default;
+INSERT INTO t1 SELECT 1;
+ERROR 21S01: Column count doesn't match value count at row 1
+connection con2;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+disconnect con2;
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1;
+#
+# MDEV-22674 Server crash in compare_bin, ASAN heap-buffer-overflow in
+# _ma_dpointer, Assertion `!info->s->have_versioning ||
+# info->s->lock_key_trees' failed in restore_table_state_after_repair
+#
+CREATE TABLE t1 (id INT, d DATETIME, PRIMARY KEY(d,id),INDEX(d)) ENGINE=Aria;
+INSERT INTO t1 SELECT seq, NOW() FROM seq_1_to_500;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+connect con1,localhost,root,,test;
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 (id) SELECT b FROM t2;
+connection default;
+INSERT INTO t1 SELECT a FROM t2;
+ERROR 21S01: Column count doesn't match value count at row 1
+connection con1;
+ERROR 42S22: Unknown column 'b' in 'field list'
+disconnect con1;
+connection default;
+drop table t1, t2;
+# This is also in MDEV-22674
+CREATE TABLE t1 (id INT, d DATETIME, PRIMARY KEY(d,id),INDEX(d)) ENGINE=Aria;
+INSERT INTO t1 SELECT seq, NOW() FROM seq_1_to_500;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 (id) SELECT b FROM t2;
+ERROR 42S22: Unknown column 'b' in 'field list'
+INSERT INTO t1 SELECT a FROM t2;
+ERROR 21S01: Column count doesn't match value count at row 1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+500
+DROP TABLE t1,t2;
+#
+# MDEV-23296 Assertion `block->type == PAGECACHE_EMPTY_PAGE ||
+# block->type == PAGECACHE_READ_UNKNOWN_PAGE || block->type == type ||
+# (block->type == PAGECACHE_PLAIN_PAGE && type == PAGECACHE_LSN_PAGE)'
+# with aria_max_sort_file_size
+#
+SET @max_size.save= @@aria_max_sort_file_size;
+SET GLOBAL aria_max_sort_file_size= 0;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a CHAR(255), KEY(a)) ENGINE=Aria;
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+ALTER TABLE t1 ENABLE KEYS;
+INSERT INTO t1 VALUES (3,'nice try');
+SELECT * FROM t1;
+pk a
+1 foo
+2 bar
+3 nice try
+DROP TABLE t1;
+SET GLOBAL aria_max_sort_file_size= @max_size.save;
+#
+# End of 10.4 test
+#
diff --git a/mysql-test/suite/maria/alter.test b/mysql-test/suite/maria/alter.test
index 31eeac1df87..f2950f0a6d3 100644
--- a/mysql-test/suite/maria/alter.test
+++ b/mysql-test/suite/maria/alter.test
@@ -1,6 +1,8 @@
# Testing of potential problems in Aria and alter table
-- source include/have_maria.inc
+-- source include/have_innodb.inc
+-- source include/have_sequence.inc
drop table if exists t1;
@@ -90,3 +92,103 @@ DROP TABLE t1;
--echo #
--echo # End of 10.2 test
--echo #
+
+--echo #
+--echo # MDEV-17665 Assertion `!share || share->page_type == PAGECACHE_LSN_PAGE',
+--echo # `type != PAGECACHE_READ_UNKNOWN_PAGE' and similar ones upon concurrent
+--echo # Aria operations
+--echo #
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=Aria;
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
+
+--connect (con1,localhost,root,,test)
+--connect (con2,localhost,root,,test)
+--send
+ INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
+
+--connection con1
+--send
+ FLUSH TABLES;
+
+--connection default
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+INSERT INTO t1 SELECT 1;
+
+# Cleanup
+--connection con2
+--error ER_DUP_ENTRY
+--reap
+--disconnect con2
+--connection con1
+--reap
+--disconnect con1
+--connection default
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-22674 Server crash in compare_bin, ASAN heap-buffer-overflow in
+--echo # _ma_dpointer, Assertion `!info->s->have_versioning ||
+--echo # info->s->lock_key_trees' failed in restore_table_state_after_repair
+--echo #
+
+CREATE TABLE t1 (id INT, d DATETIME, PRIMARY KEY(d,id),INDEX(d)) ENGINE=Aria;
+INSERT INTO t1 SELECT seq, NOW() FROM seq_1_to_500;
+
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+
+--connect (con1,localhost,root,,test)
+ALTER TABLE t1 DISABLE KEYS;
+--send
+ INSERT INTO t1 (id) SELECT b FROM t2;
+
+--connection default
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+INSERT INTO t1 SELECT a FROM t2;
+
+# Cleanup
+--connection con1
+--error ER_BAD_FIELD_ERROR
+--reap
+--disconnect con1
+
+--connection default
+drop table t1, t2;
+
+--echo # This is also in MDEV-22674
+
+CREATE TABLE t1 (id INT, d DATETIME, PRIMARY KEY(d,id),INDEX(d)) ENGINE=Aria;
+INSERT INTO t1 SELECT seq, NOW() FROM seq_1_to_500;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t1 DISABLE KEYS;
+--error ER_BAD_FIELD_ERROR
+INSERT INTO t1 (id) SELECT b FROM t2;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+INSERT INTO t1 SELECT a FROM t2;
+SELECT COUNT(*) FROM t1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-23296 Assertion `block->type == PAGECACHE_EMPTY_PAGE ||
+--echo # block->type == PAGECACHE_READ_UNKNOWN_PAGE || block->type == type ||
+--echo # (block->type == PAGECACHE_PLAIN_PAGE && type == PAGECACHE_LSN_PAGE)'
+--echo # with aria_max_sort_file_size
+--echo #
+
+SET @max_size.save= @@aria_max_sort_file_size;
+SET GLOBAL aria_max_sort_file_size= 0;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a CHAR(255), KEY(a)) ENGINE=Aria;
+ALTER TABLE t1 DISABLE KEYS;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+ALTER TABLE t1 ENABLE KEYS;
+INSERT INTO t1 VALUES (3,'nice try');
+SELECT * FROM t1;
+DROP TABLE t1;
+SET GLOBAL aria_max_sort_file_size= @max_size.save;
+
+--echo #
+--echo # End of 10.4 test
+--echo #
diff --git a/mysql-test/suite/maria/create.result b/mysql-test/suite/maria/create.result
index cf79542731b..801812b647f 100644
--- a/mysql-test/suite/maria/create.result
+++ b/mysql-test/suite/maria/create.result
@@ -31,6 +31,50 @@ select * from t2;
f1 f2
3 qux
DROP TABLE t1, t2;
+#
+# MDEV-23159 Assertion `table_share->tmp_table != NO_TMP_TABLE ||
+# m_lock_type != 2' + SIGSEGV in trnman_can_read_from
+# (on optimized builds)
+#
+SET @org_sql_mode=@@SQL_MODE;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Aria ROW_FORMAT=COMPRESSED;
+INSERT INTO t1 VALUES(1);
+CREATE TEMPORARY TABLE t2(b INT);
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(a) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+DROP TABLE t1,t2;
+SET SQL_MODE='';
+CREATE TABLE t1 (c INT PRIMARY KEY) ENGINE=Aria;
+CREATE TABLE t2 (d INT);
+INSERT INTO t1 VALUES (1);
+SELECT c FROM t1 WHERE (c) IN (SELECT MIN(c) FROM t2);
+c
+DROP TABLE t1,t2;
+USE test;
+SET SQL_MODE='ONLY_FULL_GROUP_BY';
+CREATE TABLE t3 (c1 DECIMAL(1,1) PRIMARY KEY,c2 DATE,c3 NUMERIC(10) UNSIGNED) ENGINE=Aria;
+CREATE TABLE t2 (f1 INTEGER ) ENGINE=Aria;
+INSERT INTO t3 VALUES (0,0,0);
+SELECT c1 FROM t3 WHERE (c1) IN (SELECT MIN(DISTINCT c1) FROM t2);
+c1
+DROP TABLE t2,t3;
+SET @@SQL_MODE=@org_sql_mode;
+#
+# MDEV-23222 SIGSEGV in maria_status | Assertion `(longlong)
+# thd->status_var.local_memory_used >= 0
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = 'MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;;
+flush tables;
+CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = 'MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;;
+Got one of the listed errors
+DROP TABLE t1;
+#
+# End of 10.3 tests
+#
CREATE TABLE t1 (a INT) ENGINE=Aria;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (b INT);
diff --git a/mysql-test/suite/maria/create.test b/mysql-test/suite/maria/create.test
index d33dd71df35..3e0be3ebb9b 100644
--- a/mysql-test/suite/maria/create.test
+++ b/mysql-test/suite/maria/create.test
@@ -41,6 +41,61 @@ CREATE OR REPLACE TABLE t2 ENGINE=Aria AS SELECT SUM(a) AS f1, IFNULL( 'qux', Ex
select * from t2;
DROP TABLE t1, t2;
+--echo #
+--echo # MDEV-23159 Assertion `table_share->tmp_table != NO_TMP_TABLE ||
+--echo # m_lock_type != 2' + SIGSEGV in trnman_can_read_from
+--echo # (on optimized builds)
+--echo #
+
+SET @org_sql_mode=@@SQL_MODE;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Aria ROW_FORMAT=COMPRESSED;
+INSERT INTO t1 VALUES(1);
+CREATE TEMPORARY TABLE t2(b INT);
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(a) FROM t2);
+DROP TABLE t1,t2;
+
+SET SQL_MODE='';
+CREATE TABLE t1 (c INT PRIMARY KEY) ENGINE=Aria;
+CREATE TABLE t2 (d INT);
+INSERT INTO t1 VALUES (1);
+SELECT c FROM t1 WHERE (c) IN (SELECT MIN(c) FROM t2);
+DROP TABLE t1,t2;
+
+USE test;
+SET SQL_MODE='ONLY_FULL_GROUP_BY';
+CREATE TABLE t3 (c1 DECIMAL(1,1) PRIMARY KEY,c2 DATE,c3 NUMERIC(10) UNSIGNED) ENGINE=Aria;
+CREATE TABLE t2 (f1 INTEGER ) ENGINE=Aria;
+INSERT INTO t3 VALUES (0,0,0);
+SELECT c1 FROM t3 WHERE (c1) IN (SELECT MIN(DISTINCT c1) FROM t2);
+DROP TABLE t2,t3;
+SET @@SQL_MODE=@org_sql_mode;
+
+--echo #
+--echo # MDEV-23222 SIGSEGV in maria_status | Assertion `(longlong)
+--echo # thd->status_var.local_memory_used >= 0
+--echo #
+
+let $mysqld_datadir= `select @@datadir`;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1);
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
+flush tables;
+--remove_file $mysqld_datadir/test/MDEV_23222.frm
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+--error 1,ER_TABLE_EXISTS_ERROR
+--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
+DROP TABLE t1;
+--disable_warnings
+--remove_file $mysqld_datadir/test/MDEV_23222.MAD
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+--remove_file $MYSQL_TMP_DIR/MDEV_23222.MAD
+--enable_warnings
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
#
# MDEV-22686 # Assertion `trn' failed in ha_maria::start_stmt
# ASAN heap-after-free in maria_status
diff --git a/mysql-test/suite/maria/maria-no-logging.result b/mysql-test/suite/maria/maria-no-logging.result
index fb175d0e326..e79686c4731 100644
--- a/mysql-test/suite/maria/maria-no-logging.result
+++ b/mysql-test/suite/maria/maria-no-logging.result
@@ -31,6 +31,9 @@ insert into t1 select * from t2;
show engine aria logs;
Type Name Status
Aria Size 24576 aria_log.00000001 unknown
+select count(*) from t1;
+count(*)
+65
connection default;
connection admin;
* shut down mysqld, removed logs, restarted it
@@ -40,6 +43,9 @@ insert into t1 select * from t2;
show engine aria logs;
Type Name Status
Aria Size 16384 aria_log.00000001 unknown
+select count(*) from t1;
+count(*)
+64
drop table t1;
connection default;
connection admin;
diff --git a/mysql-test/suite/maria/maria-no-logging.test b/mysql-test/suite/maria/maria-no-logging.test
index fb2f34f7708..5d8029156ed 100644
--- a/mysql-test/suite/maria/maria-no-logging.test
+++ b/mysql-test/suite/maria/maria-no-logging.test
@@ -48,6 +48,7 @@ insert into t1 values('a');
insert into t1 select * from t2;
--replace_regex /; .+aria_log/aria_log/
show engine aria logs;
+select count(*) from t1;
# optimization because table is empty
-- source include/maria_empty_logs.inc
@@ -55,6 +56,7 @@ truncate table t1;
insert into t1 select * from t2;
--replace_regex /; .+aria_log/aria_log/
show engine aria logs;
+select count(*) from t1;
drop table t1;
diff --git a/mysql-test/suite/mariabackup/incremental_ddl_during_backup.result b/mysql-test/suite/mariabackup/incremental_ddl_during_backup.result
index 505e834b4d1..33a3b0001a1 100644
--- a/mysql-test/suite/mariabackup/incremental_ddl_during_backup.result
+++ b/mysql-test/suite/mariabackup/incremental_ddl_during_backup.result
@@ -2,6 +2,7 @@ call mtr.add_suppression("InnoDB: New log files created");
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t3(i INT) ENGINE INNODB;
+CREATE TABLE t10(i INT PRIMARY KEY) ENGINE INNODB;
# Create full backup , modify table, then create incremental/differential backup
INSERT into t1 values(1);
# Prepare full backup, apply incremental one
diff --git a/mysql-test/suite/mariabackup/incremental_ddl_during_backup.test b/mysql-test/suite/mariabackup/incremental_ddl_during_backup.test
index fdae90132cc..b1ab17a6d8f 100644
--- a/mysql-test/suite/mariabackup/incremental_ddl_during_backup.test
+++ b/mysql-test/suite/mariabackup/incremental_ddl_during_backup.test
@@ -8,6 +8,7 @@ let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t3(i INT) ENGINE INNODB;
+CREATE TABLE t10(i INT PRIMARY KEY) ENGINE INNODB;
echo # Create full backup , modify table, then create incremental/differential backup;
--disable_result_log
@@ -20,8 +21,11 @@ INSERT into t1 values(1);
--let after_copy_test_t1=RENAME TABLE test.t1 TO test.t1_renamed
--let after_copy_test_t2=DROP TABLE test.t2
--let after_copy_test_t3=CREATE INDEX a_i ON test.t3(i);
+--let before_copy_test_t10=DROP TABLE test.t10
+--let wait_innodb_redo_before_copy=test/t10
-exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir --dbug=+d,mariabackup_events;
+# mariabackup should crash with assertion if MDEV-24026 is not fixed
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir --dbug=+d,mariabackup_events,mariabackup_inject_code;
--let after_load_tablespaces=
--disable_result_log
echo # Prepare full backup, apply incremental one;
diff --git a/mysql-test/suite/parts/r/reorganize.result b/mysql-test/suite/parts/r/reorganize.result
new file mode 100644
index 00000000000..5e6fe176edc
--- /dev/null
+++ b/mysql-test/suite/parts/r/reorganize.result
@@ -0,0 +1,13 @@
+#
+# MDEV-23248 Server crashes in mi_extra /
+# ha_partition::loop_extra_alter upon REORGANIZE
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM PARTITION BY RANGE (a) SUBPARTITION BY HASH (a) SUBPARTITIONS 70 (PARTITION p1 VALUES LESS THAN (100), PARTITION p2 VALUES LESS THAN MAXVALUE);
+INSERT INTO t1 SELECT 4, 6 FROM seq_1_to_131072;
+UPDATE t1 SET a = 7;
+set @org_debug=@@debug_dbug;
+set @@debug_dbug="+d,debug_abort_copy_partitions";
+ALTER TABLE t1 REORGANIZE PARTITION p1,p2 INTO (PARTITION p1 VALUES LESS THAN (5), PARTITION p2 VALUES LESS THAN MAXVALUE);
+ERROR 42000: Table 't1' uses an extension that doesn't exist in this MariaDB version
+set @@debug_dbug=@org_debug;
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/t/reorganize.test b/mysql-test/suite/parts/t/reorganize.test
new file mode 100644
index 00000000000..66641254468
--- /dev/null
+++ b/mysql-test/suite/parts/t/reorganize.test
@@ -0,0 +1,20 @@
+--source include/have_sequence.inc
+--source include/have_partition.inc
+--source include/have_debug.inc
+
+--echo #
+--echo # MDEV-23248 Server crashes in mi_extra /
+--echo # ha_partition::loop_extra_alter upon REORGANIZE
+--echo #
+
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM PARTITION BY RANGE (a) SUBPARTITION BY HASH (a) SUBPARTITIONS 70 (PARTITION p1 VALUES LESS THAN (100), PARTITION p2 VALUES LESS THAN MAXVALUE);
+INSERT INTO t1 SELECT 4, 6 FROM seq_1_to_131072;
+UPDATE t1 SET a = 7;
+
+set @org_debug=@@debug_dbug;
+set @@debug_dbug="+d,debug_abort_copy_partitions";
+--error ER_UNSUPPORTED_EXTENSION
+ALTER TABLE t1 REORGANIZE PARTITION p1,p2 INTO (PARTITION p1 VALUES LESS THAN (5), PARTITION p2 VALUES LESS THAN MAXVALUE);
+set @@debug_dbug=@org_debug;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/perfschema/r/dml_file_instances.result b/mysql-test/suite/perfschema/r/dml_file_instances.result
index a13c570a5ad..2680c07b07c 100644
--- a/mysql-test/suite/perfschema/r/dml_file_instances.result
+++ b/mysql-test/suite/perfschema/r/dml_file_instances.result
@@ -29,21 +29,21 @@ FILE_NAME
CREATE TABLE t_db_26152751 (a INT) ENGINE=MYISAM;
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
FILE_NAME
-t_db_26152751.frm
-t_db_26152751.MYI
t_db_26152751.MYD
+t_db_26152751.MYI
+t_db_26152751.frm
RENAME TABLE t_db_26152751 to t_db_26152751_new;
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
FILE_NAME
-t_db_26152751_new.frm
-t_db_26152751_new.MYI
t_db_26152751_new.MYD
+t_db_26152751_new.MYI
+t_db_26152751_new.frm
RENAME TABLE t_db_26152751_new to t_db_26152751;
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
FILE_NAME
-t_db_26152751.frm
-t_db_26152751.MYI
t_db_26152751.MYD
+t_db_26152751.MYI
+t_db_26152751.frm
ALTER TABLE t_db_26152751 ADD COLUMN b INT;
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
FILE_NAME
diff --git a/mysql-test/suite/perfschema/r/sxlock_func.result b/mysql-test/suite/perfschema/r/sxlock_func.result
index 04db3a42dd0..ad544f78a28 100644
--- a/mysql-test/suite/perfschema/r/sxlock_func.result
+++ b/mysql-test/suite/perfschema/r/sxlock_func.result
@@ -13,7 +13,6 @@ order by name;
name
wait/synch/sxlock/innodb/btr_search_latch
wait/synch/sxlock/innodb/dict_operation_lock
-wait/synch/sxlock/innodb/dict_table_stats
wait/synch/sxlock/innodb/fil_space_latch
wait/synch/sxlock/innodb/fts_cache_init_rw_lock
wait/synch/sxlock/innodb/fts_cache_rw_lock
diff --git a/mysql-test/suite/perfschema/t/dml_file_instances.test b/mysql-test/suite/perfschema/t/dml_file_instances.test
index ea3bf0a1917..c708c31ed55 100644
--- a/mysql-test/suite/perfschema/t/dml_file_instances.test
+++ b/mysql-test/suite/perfschema/t/dml_file_instances.test
@@ -46,16 +46,19 @@ SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t
CREATE TABLE t_db_26152751 (a INT) ENGINE=MYISAM;
+--sorted_result
--replace_regex /.*\/t_db_26152751/t_db_26152751/
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
RENAME TABLE t_db_26152751 to t_db_26152751_new;
+--sorted_result
--replace_regex /.*\/t_db_26152751/t_db_26152751/
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
RENAME TABLE t_db_26152751_new to t_db_26152751;
+--sorted_result
--replace_regex /.*\/t_db_26152751/t_db_26152751/
SELECT FILE_NAME FROM performance_schema.file_instances WHERE FILE_NAME LIKE "%t_db_26152751%";
diff --git a/mysql-test/suite/perfschema/t/show_sanity.test b/mysql-test/suite/perfschema/t/show_sanity.test
index 2d51161551d..176a615740e 100644
--- a/mysql-test/suite/perfschema/t/show_sanity.test
+++ b/mysql-test/suite/perfschema/t/show_sanity.test
@@ -417,7 +417,6 @@ insert into test.sanity values
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_DISABLE_RESIZE_BUFFER_POOL_DEBUG"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_DISABLE_SORT_FILE_CACHE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_DOUBLEWRITE"),
- ("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_DOUBLEWRITE_BATCH_SIZE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FAST_SHUTDOWN"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FILE_PER_TABLE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FILL_FACTOR"),
@@ -429,7 +428,6 @@ insert into test.sanity values
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FLUSH_NEIGHBORS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FORCE_LOAD_CORRUPTED"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FORCE_RECOVERY"),
- ("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FORCE_RECOVERY_CRASH"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FT_AUX_TABLE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FT_CACHE_SIZE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_FT_ENABLE_DIAG_PRINT"),
@@ -473,8 +471,6 @@ insert into test.sanity values
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PRINT_ALL_DEADLOCKS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PURGE_BATCH_SIZE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY"),
- ("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PURGE_RUN_NOW"),
- ("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PURGE_STOP_NOW"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_PURGE_THREADS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_RANDOM_READ_AHEAD"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_READ_AHEAD_THRESHOLD"),
diff --git a/mysql-test/suite/period/r/delete.result b/mysql-test/suite/period/r/delete.result
index 75723d17c09..d8dae7b2a99 100644
--- a/mysql-test/suite/period/r/delete.result
+++ b/mysql-test/suite/period/r/delete.result
@@ -372,7 +372,28 @@ drop procedure sp;
drop table t,t2,t3,log_tbl;
drop view v;
drop procedure log;
+# MDEV-19130 Assertion
+# `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+# failed in handler::update_auto_increment after error 167
+create or replace table t (f tinyint auto_increment null,
+s timestamp, e timestamp,
+period for app(s,e), key(f, s));
+insert into t (s,e) values
+('2021-08-22 10:28:43', '2023-09-17 00:00:00'),
+('2019-05-09 21:45:24', '2020-04-22 14:38:49');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) values ('2015-07-07 00:00:00','2020-03-11 08:48:52');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t select * from t;
+ERROR 22003: Out of range value for column 'f' at row ROW
+delete ignore from t
+for portion of app from '2015-07-07 00:00:00' to '2020-03-11 08:48:52';
+drop table t;
create table t1 (pk int, s date, e date, period for se (s,e), primary key (pk,se without overlaps));
insert into t1 values (1,'2020-01-01','2020-02-20');
delete from t1 for portion of se from '2020-01-30' to '2020-01-31';
drop table t1;
+# End of 10.5 tests
diff --git a/mysql-test/suite/period/r/overlaps.result b/mysql-test/suite/period/r/overlaps.result
index fcd54a0a942..b8f23ce413c 100644
--- a/mysql-test/suite/period/r/overlaps.result
+++ b/mysql-test/suite/period/r/overlaps.result
@@ -127,7 +127,7 @@ ERROR HY000: Period `p` is not found in table
create or replace table t(id int, s date, e date,
period for p(s,e),
primary key(id, s, p without overlaps));
-ERROR HY000: Key `(null)` cannot explicitly include column `s`
+ERROR HY000: Key `PRIMARY` cannot explicitly include column `s`
create or replace table t(id int, s date, e date,
period for p(s,e),
primary key(id));
@@ -320,4 +320,34 @@ t1 CREATE TABLE `t1` (
PARTITION `pn` CURRENT ENGINE = InnoDB)
insert into t1 values (1,'2013-01-12','2015-11-04'),
(2,'2016-03-15','2024-11-09');
+# MDEV-22714 Assertion `index->table->is_instant()' failed upon
+# multi-update on table with WITHOUT OVERLAPS
+create or replace table t (a int);
+insert into t values (0),(null),(0);
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+unique(f, p without overlaps));
+insert into t1 values (0,'2026-02-12','2036-09-16'),
+(null,'2025-03-09','2032-12-05');
+update ignore t join t1 set f = a;
+# MDEV-22639 Assertion `inited != NONE' failed in
+# handler::ha_check_overlaps upon multi-table update
+create or replace table t (f int, s date, e date, period for p(s,e),
+unique(f, p without overlaps)) engine=myisam;
+insert into t values (1,'1988-08-25','2024-03-06');
+create or replace table t1 (a int) engine=myisam;
+insert into t1 values (1),(2);
+update t join t1 set s = '2020-01-01';
+# MDEV-22608 ASAN use-after-poison in TABLE::check_period_overlaps
+create or replace table t1 (s date, e date, b bit, period for p(s,e),
+unique(b, p without overlaps)) engine=myisam;
+insert into t1 values ('2024-12-21','2034-06-29',0),
+('2024-12-21','2034-06-29',1);
+update t1 set b = 1;
+ERROR 23000: Duplicate entry '\x01-2034-06-29-2024-12-21' for key 'b'
+# MDEV-22677 Server crashes in ha_partition::open upon update on
+# partitioned HEAP table with WITHOUT OVERLAPS
+create or replace table t (id int, s date, e date, period for p(s,e),
+primary key(id, p without overlaps)
+) engine=heap partition by hash(id);
+update t set id = 1;
drop table t, t1;
diff --git a/mysql-test/suite/period/r/update.result b/mysql-test/suite/period/r/update.result
index 05d1a2eb6d3..f726b4c07cf 100644
--- a/mysql-test/suite/period/r/update.result
+++ b/mysql-test/suite/period/r/update.result
@@ -281,3 +281,29 @@ create table t1 (s date, e date, period for app(s,e), f varchar(8)) engine=aria
insert into t1 values ('2024-05-13','2026-03-25','foo');
update t1 for portion of app from '2024-04-02' to '2026-03-15' set f = 'bar';
drop table t1;
+# MDEV-19130 Assertion
+# `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+# failed in handler::update_auto_increment after error 167
+create table t1 (id int auto_increment, f int, s datetime, e datetime, period for p(s,e), primary key(id));
+insert into t1 (s,e) values ('1994-01-06','2004-11-30'),('1994-06-21','1997-06-20');
+update ignore t1 set id = 2429681664;
+Warnings:
+Warning 1264 Out of range value for column 'id' at row 1
+Warning 1264 Out of range value for column 'id' at row 2
+update ignore t1 for portion of p from '1995-07-06' to '2009-01-12' set f = 1;
+drop table t1;
+#
+# MDEV-22805 SIGSEGV in check_fields on UPDATE (optimized builds) | Assertion `thd->lex->sql_command == SQLCOM_UPDATE' failed.
+#
+CREATE TABLE t1 (a INT, b DATE, c DATE, PERIOD FOR APPTIME(b, c));
+INSERT INTO t1 VALUES(1, '1999-01-01', '2018-12-12');
+UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+ERROR 42000: This version of MariaDB doesn't yet support 'updating and querying the same temporal periods table'
+set @tmp= "UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100";
+execute immediate @tmp;
+ERROR 42000: This version of MariaDB doesn't yet support 'updating and querying the same temporal periods table'
+CREATE VIEW v1 AS SELECT * FROM t1;
+UPDATE v1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+ERROR 42S02: 'v1' is a view
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/period/t/delete.test b/mysql-test/suite/period/t/delete.test
index e7c6aabb0aa..3750e064ab9 100644
--- a/mysql-test/suite/period/t/delete.test
+++ b/mysql-test/suite/period/t/delete.test
@@ -199,11 +199,38 @@ call sp;
drop table t1;
drop procedure sp;
-
drop table t,t2,t3,log_tbl;
drop view v;
drop procedure log;
+--echo # MDEV-19130 Assertion
+--echo # `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+--echo # failed in handler::update_auto_increment after error 167
+
+create or replace table t (f tinyint auto_increment null,
+ s timestamp, e timestamp,
+ period for app(s,e), key(f, s));
+insert into t (s,e) values
+ ('2021-08-22 10:28:43', '2023-09-17 00:00:00'),
+ ('2019-05-09 21:45:24', '2020-04-22 14:38:49');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+insert into t (s,e) values ('2015-07-07 00:00:00','2020-03-11 08:48:52');
+insert into t (s,e) select s,e from t;
+insert into t (s,e) select s,e from t;
+
+--replace_regex /row \d+/row ROW/
+--error HA_ERR_AUTOINC_ERANGE
+insert into t select * from t;
+
+--disable_warnings
+delete ignore from t
+ for portion of app from '2015-07-07 00:00:00' to '2020-03-11 08:48:52';
+--enable_warnings
+
+drop table t;
+
#
# MDEV-22424 Server crashes in handler::check_duplicate_long_entry_key or Assertion `inited == NONE || lookup_handler != this' failed upon DELETE FOR PORTION on table with long unique key
#
@@ -211,3 +238,5 @@ create table t1 (pk int, s date, e date, period for se (s,e), primary key (pk,s
insert into t1 values (1,'2020-01-01','2020-02-20');
delete from t1 for portion of se from '2020-01-30' to '2020-01-31';
drop table t1;
+
+--echo # End of 10.5 tests
diff --git a/mysql-test/suite/period/t/overlaps.test b/mysql-test/suite/period/t/overlaps.test
index 30032f9898c..6cd78769d4a 100644
--- a/mysql-test/suite/period/t/overlaps.test
+++ b/mysql-test/suite/period/t/overlaps.test
@@ -299,5 +299,48 @@ insert into t1 values (1,'2013-01-12','2015-11-04'),
(2,'2016-03-15','2024-11-09');
+--echo # MDEV-22714 Assertion `index->table->is_instant()' failed upon
+--echo # multi-update on table with WITHOUT OVERLAPS
+
+create or replace table t (a int);
+insert into t values (0),(null),(0);
+
+create or replace table t1 (f int, s date, e date, period for p(s,e),
+ unique(f, p without overlaps));
+
+insert into t1 values (0,'2026-02-12','2036-09-16'),
+ (null,'2025-03-09','2032-12-05');
+
+update ignore t join t1 set f = a;
+
+--echo # MDEV-22639 Assertion `inited != NONE' failed in
+--echo # handler::ha_check_overlaps upon multi-table update
+
+create or replace table t (f int, s date, e date, period for p(s,e),
+ unique(f, p without overlaps)) engine=myisam;
+insert into t values (1,'1988-08-25','2024-03-06');
+create or replace table t1 (a int) engine=myisam;
+insert into t1 values (1),(2);
+
+update t join t1 set s = '2020-01-01';
+
+
+--echo # MDEV-22608 ASAN use-after-poison in TABLE::check_period_overlaps
+
+create or replace table t1 (s date, e date, b bit, period for p(s,e),
+ unique(b, p without overlaps)) engine=myisam;
+insert into t1 values ('2024-12-21','2034-06-29',0),
+ ('2024-12-21','2034-06-29',1);
+--error ER_DUP_ENTRY
+update t1 set b = 1;
+
+
+--echo # MDEV-22677 Server crashes in ha_partition::open upon update on
+--echo # partitioned HEAP table with WITHOUT OVERLAPS
+
+create or replace table t (id int, s date, e date, period for p(s,e),
+ primary key(id, p without overlaps)
+ ) engine=heap partition by hash(id);
+update t set id = 1;
drop table t, t1;
diff --git a/mysql-test/suite/period/t/update.test b/mysql-test/suite/period/t/update.test
index 0f54dd80eec..3f4dd2bdc68 100644
--- a/mysql-test/suite/period/t/update.test
+++ b/mysql-test/suite/period/t/update.test
@@ -173,3 +173,35 @@ update t1 for portion of app from '2024-04-02' to '2026-03-15' set f = 'bar';
# cleanup
drop table t1;
+
+--echo # MDEV-19130 Assertion
+--echo # `next_insert_id >= auto_inc_interval_for_cur_row.minimum()'
+--echo # failed in handler::update_auto_increment after error 167
+create table t1 (id int auto_increment, f int, s datetime, e datetime, period for p(s,e), primary key(id));
+insert into t1 (s,e) values ('1994-01-06','2004-11-30'),('1994-06-21','1997-06-20');
+update ignore t1 set id = 2429681664;
+update ignore t1 for portion of p from '1995-07-06' to '2009-01-12' set f = 1;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-22805 SIGSEGV in check_fields on UPDATE (optimized builds) | Assertion `thd->lex->sql_command == SQLCOM_UPDATE' failed.
+--echo #
+CREATE TABLE t1 (a INT, b DATE, c DATE, PERIOD FOR APPTIME(b, c));
+
+INSERT INTO t1 VALUES(1, '1999-01-01', '2018-12-12');
+
+# Without a patch the following statement crashs a server built in debug mode
+let $stmt= UPDATE t1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+--error ER_NOT_SUPPORTED_YET
+eval $stmt;
+eval set @tmp= "$stmt";
+--error ER_NOT_SUPPORTED_YET
+execute immediate @tmp;
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+--error ER_IT_IS_A_VIEW
+UPDATE v1 FOR PORTION OF APPTIME FROM (SELECT '1999-01-01' FROM t1 WHERE a=2) TO '2018-01-01' SET a = 100;
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index 82e16c9be25..ab726a0e22f 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -227,6 +227,21 @@ set global server_audit_logging= on;
disconnect cn1;
drop user user1@localhost;
set global server_audit_events='';
+CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
+CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd';
+connect(localhost,plug,plug_dest,test,MYSQL_PORT,MYSQL_SOCK);
+connect plug_con,localhost,plug,plug_dest;
+ERROR 28000: Access denied for user 'plug'@'localhost' (using password: YES)
+GRANT PROXY ON plug_dest TO plug;
+connect plug_con,localhost,plug,plug_dest;
+connection plug_con;
+select USER(),CURRENT_USER();
+USER() CURRENT_USER()
+plug@localhost plug_dest@%
+connection default;
+disconnect plug_con;
+DROP USER plug;
+DROP USER plug_dest;
set global server_audit_query_log_limit= 15;
select (1), (2), (3), (4);
1 2 3 4
@@ -416,6 +431,46 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER plug IDENTIFIED WITH \'test_plugin_server\' AS \'plug_dest\'',0
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER plug_dest IDENTIFIED BY *****',0
+TIME,HOSTNAME,plug,localhost,ID,0,FAILED_CONNECT,,,ID
+TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,,,0
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT PROXY ON plug_dest TO plug',0
+TIME,HOSTNAME,plug,localhost,ID,0,PROXY_CONNECT,test,`plug_dest`@`%`,0
+TIME,HOSTNAME,plug,localhost,ID,0,CONNECT,test,,0
+TIME,HOSTNAME,plug,localhost,ID,0,DISCONNECT,test,,0
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'DROP USER plug',0
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,db,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,tables_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,columns_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,procs_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proxies_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,roles_mapping,
+TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,global_priv,
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'DROP USER plug_dest',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select \'A\', ',0
diff --git a/mysql-test/suite/plugins/r/test_sql_service.result b/mysql-test/suite/plugins/r/test_sql_service.result
new file mode 100644
index 00000000000..af414d6c6e7
--- /dev/null
+++ b/mysql-test/suite/plugins/r/test_sql_service.result
@@ -0,0 +1,8 @@
+install plugin test_sql_service soname 'test_sql_service';
+set global test_sql_service_run_test= 1;
+show status like 'test_sql_service%';
+Variable_name Value
+Test_sql_service_passed 0
+uninstall plugin test_sql_service;
+Warnings:
+Warning 1620 Plugin is busy and will be uninstalled on shutdown
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 2a76c1eaadc..787541f7ca0 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -1,4 +1,4 @@
-
+--source include/have_plugin_auth.inc
--source include/not_embedded.inc
if (!$SERVER_AUDIT_SO) {
@@ -174,6 +174,25 @@ drop user user1@localhost;
set global server_audit_events='';
+CREATE USER plug IDENTIFIED WITH 'test_plugin_server' AS 'plug_dest';
+CREATE USER plug_dest IDENTIFIED BY 'plug_dest_passwd';
+--sleep 2
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_ACCESS_DENIED_ERROR : this should fail : no grant
+connect(plug_con,localhost,plug,plug_dest);
+--sleep 2
+GRANT PROXY ON plug_dest TO plug;
+--sleep 2
+connect(plug_con,localhost,plug,plug_dest);
+connection plug_con;
+select USER(),CURRENT_USER();
+connection default;
+disconnect plug_con;
+--sleep 2
+--sleep 2
+DROP USER plug;
+DROP USER plug_dest;
+
set global server_audit_query_log_limit= 15;
select (1), (2), (3), (4);
select 'A', 'B', 'C', 'D';
diff --git a/mysql-test/suite/plugins/t/test_sql_service.opt b/mysql-test/suite/plugins/t/test_sql_service.opt
new file mode 100644
index 00000000000..089ed94b688
--- /dev/null
+++ b/mysql-test/suite/plugins/t/test_sql_service.opt
@@ -0,0 +1,2 @@
+--thread_handling='one-thread-per-connection'
+
diff --git a/mysql-test/suite/plugins/t/test_sql_service.test b/mysql-test/suite/plugins/t/test_sql_service.test
new file mode 100644
index 00000000000..3384b523bda
--- /dev/null
+++ b/mysql-test/suite/plugins/t/test_sql_service.test
@@ -0,0 +1,18 @@
+
+--source include/not_embedded.inc
+
+if (!$TEST_SQL_SERVICE_SO) {
+ skip No TEST_SQL_SERVICE plugin;
+}
+
+# An unfortunate wait for check-testcase.test to complete disconnect.
+let count_sessions= 1;
+source include/wait_until_count_sessions.inc;
+
+install plugin test_sql_service soname 'test_sql_service';
+
+set global test_sql_service_run_test= 1;
+show status like 'test_sql_service%';
+
+uninstall plugin test_sql_service;
+
diff --git a/mysql-test/suite/roles/set_default_role_clear.result b/mysql-test/suite/roles/set_default_role_clear.result
index 6441dfc2aa4..281ed7e45ea 100644
--- a/mysql-test/suite/roles/set_default_role_clear.result
+++ b/mysql-test/suite/roles/set_default_role_clear.result
@@ -17,6 +17,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
+SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
select user, host, default_role from mysql.user where user='test_user';
User Host default_role
test_user localhost test_role
diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result
index 533a646e6e3..fec43b8e763 100644
--- a/mysql-test/suite/roles/set_default_role_for.result
+++ b/mysql-test/suite/roles/set_default_role_for.result
@@ -21,6 +21,7 @@ Grants for user_a@localhost
GRANT `role_a` TO `user_a`@`localhost`
GRANT USAGE ON *.* TO `user_a`@`localhost`
GRANT SELECT ON *.* TO `role_a`
+SET DEFAULT ROLE role_a FOR 'user_a'@'localhost'
select user, host, default_role from mysql.user where user like 'user_%';
User Host default_role
user_a localhost role_a
@@ -42,6 +43,7 @@ Grants for user_b@localhost
GRANT `role_b` TO `user_b`@`localhost`
GRANT USAGE ON *.* TO `user_b`@`localhost`
GRANT INSERT, UPDATE ON *.* TO `role_b`
+SET DEFAULT ROLE role_b FOR 'user_b'@'localhost'
select user, host, default_role from mysql.user where user like 'user_%';
ERROR 42000: SELECT command denied to user 'user_b'@'localhost' for table 'user'
set default role NONE for user_a@localhost;
diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result
index c8789594593..08087acc51f 100644
--- a/mysql-test/suite/roles/set_default_role_invalid.result
+++ b/mysql-test/suite/roles/set_default_role_invalid.result
@@ -24,6 +24,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
+SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
select user, host, default_role from mysql.user where user='test_user';
User Host default_role
test_user localhost test_role
@@ -71,6 +72,7 @@ GRANT `r1` TO `b`@`%`
GRANT `r2` TO `b`@`%`
GRANT USAGE ON *.* TO `b`@`%`
GRANT SELECT ON `mysql`.* TO `b`@`%`
+SET DEFAULT ROLE r2 FOR 'b'@'%'
SET DEFAULT ROLE r1 FOR a;
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
SELECT CURRENT_ROLE;
@@ -96,6 +98,7 @@ GRANT `r1` TO `b`@`%`
GRANT `r2` TO `b`@`%`
GRANT USAGE ON *.* TO `b`@`%`
GRANT SELECT, UPDATE ON `mysql`.* TO `b`@`%`
+SET DEFAULT ROLE r2 FOR 'b'@'%'
SET DEFAULT ROLE r1 FOR a;
ERROR OP000: User `a@%` has not been granted role `r1`
SET DEFAULT ROLE invalid_role;
diff --git a/mysql-test/suite/roles/set_default_role_new_connection.result b/mysql-test/suite/roles/set_default_role_new_connection.result
index dbf0db863c6..71035737f99 100644
--- a/mysql-test/suite/roles/set_default_role_new_connection.result
+++ b/mysql-test/suite/roles/set_default_role_new_connection.result
@@ -23,6 +23,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
+SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
select user, host, default_role from mysql.user where user = 'test_user';
User Host default_role
test_user localhost test_role
@@ -51,6 +52,7 @@ Grants for test_user@localhost
GRANT `test_role` TO `test_user`@`localhost`
GRANT USAGE ON *.* TO `test_user`@`localhost`
GRANT SELECT ON *.* TO `test_role`
+SET DEFAULT ROLE test_role FOR 'test_user'@'localhost'
select user, host, default_role from mysql.user where user = 'test_user';
User Host default_role
test_user localhost test_role
diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def
index 640c4b56cd0..6ea0b84f32a 100644
--- a/mysql-test/suite/rpl/disabled.def
+++ b/mysql-test/suite/rpl/disabled.def
@@ -16,7 +16,6 @@ rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition
rpl_row_binlog_max_cache_size : MDEV-11092
rpl_row_index_choice : MDEV-11666
rpl_semi_sync_after_sync : fails after MDEV-16172
-rpl_slave_grp_exec: MDEV-10514
rpl_auto_increment_update_failure : disabled for now
rpl_current_user : waits for MDEV-22374 fix
rpl_parallel2 : waits for MDEV-23089
diff --git a/mysql-test/suite/rpl/r/rpl_create_drop_view.result b/mysql-test/suite/rpl/r/rpl_create_drop_view.result
index facd40a6018..079eb749b37 100644
--- a/mysql-test/suite/rpl/r/rpl_create_drop_view.result
+++ b/mysql-test/suite/rpl/r/rpl_create_drop_view.result
@@ -93,7 +93,8 @@ id
80
40
connection master;
-DROP VIEW v1;
+RENAME TABLE v1 TO v2;
+DROP VIEW v2;
DROP TABLE t1;
DROP VIEW v1;
ERROR 42S02: Unknown VIEW: 'test.v1'
diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
index 1f352e68bc7..35e5de7b15a 100644
--- a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
+++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
@@ -3,20 +3,66 @@ include/master-slave.inc
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'");
connection master;
-DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
-CREATE DATABASE `#mysql50#mysqltest-1`;
+CREATE DATABASE `mysqltest-1`;
connection slave;
connection master;
connection slave;
connection master;
Master position is not changed
connection slave;
-STOP SLAVE SQL_THREAD;
-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;
+ALTER TABLE mysql.slow_log DROP COLUMN thread_id, DROP COLUMN rows_affected;
+DROP DATABASE `mysqltest-1`;
+connection slave;
+connection slave;
+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'
connection master;
connection master;
Master position has been changed
-DROP DATABASE `mysqltest-1`;
connection slave;
-DROP DATABASE `#mysql50#mysqltest-1`;
+connection slave;
+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_parallel_retry.result b/mysql-test/suite/rpl/r/rpl_parallel_retry.result
index 66428c94086..b43556815d1 100644
--- a/mysql-test/suite/rpl/r/rpl_parallel_retry.result
+++ b/mysql-test/suite/rpl/r/rpl_parallel_retry.result
@@ -372,7 +372,7 @@ connection server_2;
SET @old_dbug= @@GLOBAL.debug_dbug;
SET @@GLOBAL.debug_dbug="+d,rpl_parallel_simulate_wait_at_retry";
include/start_slave.inc
-# Make sure the 2nd seqno_1001 worker has gotten to waiting
+# Make sure both workers are waiting at their sync points
# Signal to the 1st to proceed after it has reached termination state
SET @@DEBUG_SYNC='now SIGNAL proceed_by_1000';
connection spoiler_21;
diff --git a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result
index c0140962a56..e0272b71192 100644
--- a/mysql-test/suite/rpl/r/rpl_start_stop_slave.result
+++ b/mysql-test/suite/rpl/r/rpl_start_stop_slave.result
@@ -5,10 +5,12 @@ set @time_before_kill := (select CURRENT_TIMESTAMP);
[Time before the query]
[Connection ID of the slave I/O thread found]
kill <connection_id>;
+include/wait_for_slave_io_to_stop.inc
set @time_after_kill := (select CURRENT_TIMESTAMP);
[Time after the query]
[Killing of the slave IO thread was successful]
START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
connection master;
create table t1 (a int primary key);
connection slave;
diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_view.test b/mysql-test/suite/rpl/t/rpl_create_drop_view.test
index c26243ab3c6..4abb3ffb252 100644
--- a/mysql-test/suite/rpl/t/rpl_create_drop_view.test
+++ b/mysql-test/suite/rpl/t/rpl_create_drop_view.test
@@ -38,7 +38,8 @@ SELECT * FROM t1;
SELECT * FROM v1;
connection master;
-DROP VIEW v1;
+RENAME TABLE v1 TO v2;
+DROP VIEW v2;
DROP TABLE t1;
--error ER_UNKNOWN_VIEW
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
index 622e66c5263..0262998798a 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
@@ -55,8 +55,17 @@ FLUSH BINARY LOGS;
--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
--eval PURGE BINARY LOGS TO '$purge_to_binlog';
# with final removal of the extra domain
+###adding to debug info to catch the failure (1076):
+--error 0,1076
--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id)
+
+if ($mysql_errno == 1076) {
+ --echo ### Failure "Could not delete gtid domain"
+ --source include/show_rpl_debug_info.inc
+ }
+
SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state;
+
--connection slave
SELECT @@global.gtid_slave_pos;
# start the slave sucessfully
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_parallel_retry.test b/mysql-test/suite/rpl/t/rpl_parallel_retry.test
index 96863f9021d..55da54e3c8c 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel_retry.test
+++ b/mysql-test/suite/rpl/t/rpl_parallel_retry.test
@@ -426,8 +426,8 @@ SET @old_dbug= @@GLOBAL.debug_dbug;
SET @@GLOBAL.debug_dbug="+d,rpl_parallel_simulate_wait_at_retry";
--source include/start_slave.inc
---echo # Make sure the 2nd seqno_1001 worker has gotten to waiting
---let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE '%debug sync point: now%';
+--echo # Make sure both workers are waiting at their sync points
+--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE '%debug sync point%';
--source include/wait_condition.inc
diff --git a/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test b/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
index 928ad7e5e09..5b08b2cd463 100644
--- a/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
+++ b/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test
@@ -101,6 +101,7 @@ TRUNCATE t3;
ALTER TABLE t1 ADD PRIMARY KEY (a);
ALTER TABLE t2 ADD PRIMARY KEY (a);
ALTER TABLE t3 ADD PRIMARY KEY (a);
+
--sync_slave_with_master
RENAME TABLE t3 TO t3_bak;
@@ -146,7 +147,7 @@ ALTER TABLE t1 ENGINE=InnoDB;
ALTER TABLE t2 ENGINE=InnoDB;
ALTER TABLE t3 ENGINE=InnoDB;
---connection slave
+--sync_slave_with_master
RENAME TABLE t3 TO t3_bak;
--connection master
diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
index a38ac8fc6a1..23b25b1bf85 100644
--- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
+++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
@@ -38,8 +38,8 @@ set @time_before_kill := (select CURRENT_TIMESTAMP);
--replace_regex /kill [0-9]*/kill <connection_id>/
--eval kill $connection_id
-let $wait_condition= SELECT COUNT(*) = 0 FROM information_schema.processlist where id=$connection_id;
---source include/wait_condition.inc
+--source include/wait_for_slave_io_to_stop.inc
+
set @time_after_kill := (select CURRENT_TIMESTAMP);
--echo [Time after the query]
@@ -52,6 +52,7 @@ if(`select TIMESTAMPDIFF(SECOND,@time_after_kill, @time_before_kill) > 60`)
--echo [Killing of the slave IO thread was successful]
START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
# Ensure that the slave io thread started properly
connection master;
diff --git a/mysql-test/suite/s3/alter.result b/mysql-test/suite/s3/alter.result
index 0764d661468..da9ddb11ea7 100644
--- a/mysql-test/suite/s3/alter.result
+++ b/mysql-test/suite/s3/alter.result
@@ -25,6 +25,14 @@ t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 COMMENT='hello'
+alter table t1 engine=s3;
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 COMMENT='hello'
select count(*), sum(a), sum(b) from t1;
count(*) sum(a) sum(b)
1000 500500 510500
diff --git a/mysql-test/suite/s3/alter.test b/mysql-test/suite/s3/alter.test
index 791d7750cb1..4504804c91a 100644
--- a/mysql-test/suite/s3/alter.test
+++ b/mysql-test/suite/s3/alter.test
@@ -1,5 +1,6 @@
--source include/have_s3.inc
--source include/have_sequence.inc
+--source include/have_innodb.inc
#
# Create unique database for running the tests
@@ -21,6 +22,9 @@ alter table t1 comment="hello";
show create table t1;
alter table t1 engine=aria;
show create table t1;
+alter table t1 engine=s3;
+alter table t1 engine=innodb;
+show create table t1;
select count(*), sum(a), sum(b) from t1;
drop table t1;
diff --git a/mysql-test/suite/s3/disabled.def b/mysql-test/suite/s3/disabled.def
index 8eae300e21e..e69de29bb2d 100644
--- a/mysql-test/suite/s3/disabled.def
+++ b/mysql-test/suite/s3/disabled.def
@@ -1,3 +0,0 @@
-replication_partition : MDEV-23730: Server crashes in ha_maria::extra
-replication_mixed : MDEV-23770: Replication failure
-replication_stmt : MDEV-23770: Replication failure
diff --git a/mysql-test/suite/s3/my.cnf b/mysql-test/suite/s3/my.cnf
index a979bf31817..e5f7d4e59f1 100644
--- a/mysql-test/suite/s3/my.cnf
+++ b/mysql-test/suite/s3/my.cnf
@@ -2,7 +2,7 @@
!include include/default_client.cnf
[mysqld.1]
-plugin-maturity = alpha
+plugin-maturity = gamma
plugin-load-add=@ENV.HA_S3_SO
s3=ON
#s3-host-name=s3.amazonaws.com
diff --git a/mysql-test/suite/s3/partition.result b/mysql-test/suite/s3/partition.result
index 7020ce88483..ee837611d50 100644
--- a/mysql-test/suite/s3/partition.result
+++ b/mysql-test/suite/s3/partition.result
@@ -63,7 +63,7 @@ count(*)
ALTER TABLE t2 CHECK PARTITION p3;
Table Op Msg_type Msg_text
s3.t2 check error Subpartition p3sp0 returned error
-s3.t2 check error Unknown - internal error 131 during operation
+s3.t2 check error Unknown - internal error 165 during operation
SELECT count(*) FROM t2;
count(*)
6
diff --git a/mysql-test/suite/s3/partition.test b/mysql-test/suite/s3/partition.test
index b60eb1bf2dd..03bbc2f0da9 100644
--- a/mysql-test/suite/s3/partition.test
+++ b/mysql-test/suite/s3/partition.test
@@ -1,8 +1,3 @@
-if (`SELECT @@s3_host_name <> "s3.amazonaws.com"`)
-{
- skip The test is disabled for emulator environment due to MDEV-23648;
-}
-
--source include/have_partition.inc
--source include/have_s3.inc
--source create_database.inc
diff --git a/mysql-test/suite/s3/partition_move.test b/mysql-test/suite/s3/partition_move.test
index 1a5c45ca0b1..35edbd75b5a 100644
--- a/mysql-test/suite/s3/partition_move.test
+++ b/mysql-test/suite/s3/partition_move.test
@@ -1,8 +1,3 @@
-if (`SELECT @@s3_host_name <> "s3.amazonaws.com"`)
-{
- skip The test is disabled for emulator environment due to MDEV-23648;
-}
-
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/have_s3.inc
diff --git a/mysql-test/suite/s3/replication.inc b/mysql-test/suite/s3/replication.inc
index 26dd9a5da25..d790c70f221 100644
--- a/mysql-test/suite/s3/replication.inc
+++ b/mysql-test/suite/s3/replication.inc
@@ -20,6 +20,8 @@ connection master;
create table t1 (a int, b int) engine=aria;
insert into t1 select seq,seq+10 from seq_1_to_10;
+sync_slave_with_master;
+connection master;
alter table t1 engine=s3;
show create table t1;
@@ -116,12 +118,18 @@ connection slave;
stop slave;
connection master;
rename table t1 to t2;
-create table t1 (a int, b int) engine=aria;
+# Check the different create options with the table
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
alter table t1 engine=s3;
connection slave;
start slave;
connection master;
sync_slave_with_master;
+show create table t1;
select * from t1 limit 2;
select * from t2 limit 2;
connection master;
diff --git a/mysql-test/suite/s3/replication_delayed.cnf b/mysql-test/suite/s3/replication_delayed.cnf
new file mode 100644
index 00000000000..9313546f637
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.cnf
@@ -0,0 +1,3 @@
+!include ../rpl/my.cnf
+!include ./my.cnf
+!include ./slave.cnf
diff --git a/mysql-test/suite/s3/replication_delayed.result b/mysql-test/suite/s3/replication_delayed.result
new file mode 100644
index 00000000000..cad8b905d0b
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.result
@@ -0,0 +1,124 @@
+include/master-slave.inc
+[connection master]
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+connection slave;
+use database;
+connection master;
+#
+# MDEV-23691 S3 storage engine: delayed slave can drop the table
+#
+connection slave;
+stop slave;
+connection master;
+create /*or replace*/ table t100 (
+pk varchar(100)
+) engine = 'innodb';
+insert into t100 values ('old data');
+alter table t100 engine=s3;
+drop table t100;
+create /*or replace*/ table t100 (
+pk varchar(100)
+) engine= innodb;
+insert into t100 select 'new data' from seq_1_to_10;
+alter table t100 engine=s3;
+select count(*), 'before slave start' from t100;
+count(*) before slave start
+10 before slave start
+connection slave;
+start slave;
+connection master;
+connection slave;
+connection master;
+flush tables;
+select count(*), 'after slave start' from t100;
+count(*) after slave start
+10 after slave start
+show create table t100;
+Table Create Table
+t100 CREATE TABLE `t100` (
+ `pk` varchar(100) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
+connection slave;
+select count(*) from t100;
+count(*)
+10
+connection master;
+drop table t100;
+#
+# Test delayed slave with inserts
+#
+connection slave;
+stop slave;
+connection master;
+create table t1 (a int) engine=innodb;
+insert into t1 values (1),(2),(3);
+insert into t1 select * from seq_4_to_6;
+alter table t1 engine=s3;
+connection slave;
+start slave;
+connection master;
+connection slave;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+connection master;
+drop table t1;
+#
+# Check slave binary log
+#
+connection slave;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # create database database
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create /*or replace*/ table t100 (
+pk varchar(100)
+) engine = 'innodb'
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t100 values ('old data')
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t100 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t100` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create /*or replace*/ table t100 (
+pk varchar(100)
+) engine= innodb
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t100 select 'new data' from seq_1_to_10
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t100 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; flush tables
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t100` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=innodb
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 values (1),(2),(3)
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Query # # use `database`; insert into t1 select * from seq_4_to_6
+slave-bin.000001 # Query # # COMMIT
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+connection master;
+#
+# clean up
+#
+include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_delayed.test b/mysql-test/suite/s3/replication_delayed.test
new file mode 100644
index 00000000000..0ae93b850c4
--- /dev/null
+++ b/mysql-test/suite/s3/replication_delayed.test
@@ -0,0 +1,115 @@
+--source include/have_s3.inc
+--source include/have_innodb.inc
+--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
+--source include/have_sequence.inc
+
+# First clear the binlog
+set binlog_format=mixed;
+RESET MASTER;
+connection slave;
+set binlog_format=mixed;
+RESET MASTER;
+connection master;
+
+#
+# Create unique database for running the tests
+#
+--source create_database.inc
+sync_slave_with_master;
+--replace_result $database database
+--eval use $database
+connection master;
+
+--echo #
+--echo # MDEV-23691 S3 storage engine: delayed slave can drop the table
+--echo #
+
+connection slave;
+stop slave;
+connection master;
+
+#
+# Create version 1 of the table
+#
+
+create /*or replace*/ table t100 (
+ pk varchar(100)
+) engine = 'innodb';
+
+insert into t100 values ('old data');
+alter table t100 engine=s3;
+
+#
+# Create version 2 of the table
+#
+drop table t100;
+create /*or replace*/ table t100 (
+ pk varchar(100)
+) engine= innodb;
+insert into t100 select 'new data' from seq_1_to_10;
+alter table t100 engine=s3;
+
+select count(*), 'before slave start' from t100;
+
+#
+# Now, start the slave
+#
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+#select count(*) from t100;
+connection master;
+
+flush tables;
+select count(*), 'after slave start' from t100;
+show create table t100;
+
+connection slave;
+
+select count(*) from t100;
+
+connection master;
+
+drop table t100;
+
+--echo #
+--echo # Test delayed slave with inserts
+--echo #
+
+
+# Stop slave
+
+connection slave;
+stop slave;
+connection master;
+
+# Create tables with data while slave is stopped
+create table t1 (a int) engine=innodb;
+insert into t1 values (1),(2),(3);
+insert into t1 select * from seq_4_to_6;
+alter table t1 engine=s3;
+
+connection slave;
+start slave;
+connection master;
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+--echo #
+--echo # Check slave binary log
+--echo #
+
+sync_slave_with_master;
+--let $binlog_database=$database
+--source include/show_binlog_events.inc
+connection master;
+
+--echo #
+--echo # clean up
+--echo #
+--source drop_database.inc
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/s3/replication_mixed.result b/mysql-test/suite/s3/replication_mixed.result
index 47cf907b187..077ae2bf1f9 100644
--- a/mysql-test/suite/s3/replication_mixed.result
+++ b/mysql-test/suite/s3/replication_mixed.result
@@ -13,6 +13,8 @@ connection master;
#
create table t1 (a int, b int) engine=aria;
insert into t1 select seq,seq+10 from seq_1_to_10;
+connection slave;
+connection master;
alter table t1 engine=s3;
show create table t1;
Table Create Table
@@ -134,14 +136,25 @@ connection slave;
stop slave;
connection master;
rename table t1 to t2;
-create table t1 (a int, b int) engine=aria;
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
alter table t1 engine=s3;
connection slave;
start slave;
connection master;
connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
select * from t1 limit 2;
-a b
+a b c
select * from t2 limit 2;
a b f
1 11 NULL
@@ -238,7 +251,15 @@ slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table if not exists t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create or replace table t1 (a int, b int, c int) engine=aria
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
slave-bin.000001 # Gtid # # GTID #-#-#
diff --git a/mysql-test/suite/s3/replication_partition.result b/mysql-test/suite/s3/replication_partition.result
index 40fb2aec698..2b9297ea9a0 100644
--- a/mysql-test/suite/s3/replication_partition.result
+++ b/mysql-test/suite/s3/replication_partition.result
@@ -89,10 +89,18 @@ select sum(c1)+0 from t1;
sum(c1)+0
600
stop slave;
-flush tables;
-select sum(c1)+0 from t1;
-sum(c1)+0
-600
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=S3 DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`c1`)
+(PARTITION `p1` VALUES LESS THAN (200) ENGINE = S3,
+ PARTITION `p2` VALUES LESS THAN (300) ENGINE = S3,
+ PARTITION `p3` VALUES LESS THAN (400) ENGINE = S3,
+ PARTITION `p4` VALUES LESS THAN (500) ENGINE = S3)
connection master;
drop table t1;
connection slave;
@@ -204,8 +212,6 @@ slave-bin.000001 # Query # # use `database`; alter table t1 engine=S3
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; ALTER TABLE t1 ADD PARTITION (PARTITION p4 VALUES LESS THAN (500))
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `database`; flush tables
-slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; CREATE TABLE t2 (
diff --git a/mysql-test/suite/s3/replication_partition.test b/mysql-test/suite/s3/replication_partition.test
index 0430d14d7a7..8a8699920bf 100644
--- a/mysql-test/suite/s3/replication_partition.test
+++ b/mysql-test/suite/s3/replication_partition.test
@@ -7,6 +7,12 @@
--source create_database.inc
sync_slave_with_master;
+
+if (`select @@s3_slave_ignore_updates <> 1`)
+{
+ die "Slave is not configured with s3-slave-ignore-updates=1";
+}
+
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_result $database database
--eval use $database
@@ -65,20 +71,8 @@ sync_slave_with_master;
select sum(c1)+0 from t1;
stop slave;
-# .frm amd .par files should not exists on the salve as it has just seen the
-# ALTER TABLE which cased the removal of the .frm and .par files. The table
-# from the above "select sum()" came from table cache and was used as it's
-# id matches the one in S3
---error 1
---file_exists $MYSQLD_DATADIR/$database/t1.frm
---error 1
---file_exists $MYSQLD_DATADIR/$database/t1.par
-# Flushing the table cache will force the .frm and .par files to be
-# re-generated
-flush tables;
-select sum(c1)+0 from t1;
---file_exists $MYSQLD_DATADIR/$database/t1.frm
---file_exists $MYSQLD_DATADIR/$database/t1.par
+# Ensure the slave is using the new table
+show create table t1;
connection master;
drop table t1;
diff --git a/mysql-test/suite/s3/replication_stmt.result b/mysql-test/suite/s3/replication_stmt.result
index 56fd07445a4..8284c053cac 100644
--- a/mysql-test/suite/s3/replication_stmt.result
+++ b/mysql-test/suite/s3/replication_stmt.result
@@ -13,6 +13,8 @@ connection master;
#
create table t1 (a int, b int) engine=aria;
insert into t1 select seq,seq+10 from seq_1_to_10;
+connection slave;
+connection master;
alter table t1 engine=s3;
show create table t1;
Table Create Table
@@ -134,14 +136,25 @@ connection slave;
stop slave;
connection master;
rename table t1 to t2;
-create table t1 (a int, b int) engine=aria;
+create table t1 (a int) engine=aria;
+drop table t1;
+create table if not exists t1 (a int, b int) engine=aria;
+drop table t1;
+create or replace table t1 (a int, b int, c int) engine=aria;
alter table t1 engine=s3;
connection slave;
start slave;
connection master;
connection slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=S3 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
select * from t1 limit 2;
-a b
+a b c
select * from t2 limit 2;
a b f
1 11 NULL
@@ -238,7 +251,15 @@ slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; alter table
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; set @@sql_if_exists=1; rename table t1 to t2
slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `database`; create table t1 (a int, b int) engine=aria
+slave-bin.000001 # Query # # use `database`; create table t1 (a int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create table if not exists t1 (a int, b int) engine=aria
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; DROP TABLE IF EXISTS `t1` /* generated by server */
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `database`; create or replace table t1 (a int, b int, c int) engine=aria
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `database`; alter table t1 engine=s3
slave-bin.000001 # Gtid # # GTID #-#-#
diff --git a/mysql-test/suite/s3/slave.cnf b/mysql-test/suite/s3/slave.cnf
index b9b1da73a92..8e1349db2cc 100644
--- a/mysql-test/suite/s3/slave.cnf
+++ b/mysql-test/suite/s3/slave.cnf
@@ -1,7 +1,12 @@
[mysqld.2]
-plugin-maturity = alpha
+plugin-maturity = gamma
plugin-load-add=@ENV.HA_S3_SO
s3=ON
+s3-slave-ignore-updates=1
+
+# You can change the following when running the tests against
+# your own S3 setup
+
#s3-host-name=s3.amazonaws.com
#s3-protocol-version=Amazon
#s3-bucket=MariaDB
diff --git a/mysql-test/suite/sql_sequence/mysqldump.result b/mysql-test/suite/sql_sequence/mysqldump.result
index 5a3711ebda3..e6aedb57ea6 100644
--- a/mysql-test/suite/sql_sequence/mysqldump.result
+++ b/mysql-test/suite/sql_sequence/mysqldump.result
@@ -2,20 +2,8 @@ CREATE SEQUENCE a1 engine=aria;
CREATE TABLE t1(a INT, KEY (a)) KEY_BLOCK_SIZE=1024;
insert into t1 values (1),(2);
CREATE SEQUENCE x1 engine=innodb;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `a1` (
- `next_not_cached_value` bigint(21) NOT NULL,
- `minimum_value` bigint(21) NOT NULL,
- `maximum_value` bigint(21) NOT NULL,
- `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
- `increment` bigint(21) NOT NULL COMMENT 'increment value',
- `cache_size` bigint(21) unsigned NOT NULL,
- `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
- `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
-) ENGINE=Aria SEQUENCE=1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO `a1` VALUES (1,1,9223372036854775806,1,1,1000,0,0);
+CREATE SEQUENCE `a1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=Aria;
+SELECT SETVAL(`a1`, 1, 0);
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t1` (
@@ -24,20 +12,8 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `t1` VALUES (1),(2);
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `x1` (
- `next_not_cached_value` bigint(21) NOT NULL,
- `minimum_value` bigint(21) NOT NULL,
- `maximum_value` bigint(21) NOT NULL,
- `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
- `increment` bigint(21) NOT NULL COMMENT 'increment value',
- `cache_size` bigint(21) unsigned NOT NULL,
- `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
- `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
-) ENGINE=InnoDB SEQUENCE=1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO `x1` VALUES (1,1,9223372036854775806,1,1,1000,0,0);
+CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB;
+SELECT SETVAL(`x1`, 1, 0);
DROP TABLE a1,t1,x1;
set default_storage_engine=InnoDB;
create sequence t1;
diff --git a/mysql-test/suite/sql_sequence/next.result b/mysql-test/suite/sql_sequence/next.result
index b1b1bb69306..76991fbe68c 100644
--- a/mysql-test/suite/sql_sequence/next.result
+++ b/mysql-test/suite/sql_sequence/next.result
@@ -534,3 +534,17 @@ select next value for s;
next value for s
-999
drop sequence s;
+#
+# MDEV-23823 NEXT VALUE crash on locked view
+#
+CREATE VIEW v AS SELECT 1;
+LOCK TABLE v READ;
+SELECT NEXT VALUE FOR v;
+ERROR 42S02: 'test.v' is not a SEQUENCE
+#
+# MDEV-24018: SIGSEGV in Item_func_nextval::update_table on SELECT SETVAL
+#
+SELECT SETVAL (v,0);
+ERROR 42S02: 'test.v' is not a SEQUENCE
+UNLOCK TABLES;
+DROP VIEW v;
diff --git a/mysql-test/suite/sql_sequence/next.test b/mysql-test/suite/sql_sequence/next.test
index a1f91bd7823..9f0eebdf774 100644
--- a/mysql-test/suite/sql_sequence/next.test
+++ b/mysql-test/suite/sql_sequence/next.test
@@ -280,3 +280,20 @@ select next value for s;
flush tables;
select next value for s;
drop sequence s;
+
+--echo #
+--echo # MDEV-23823 NEXT VALUE crash on locked view
+--echo #
+CREATE VIEW v AS SELECT 1;
+LOCK TABLE v READ;
+--error ER_NOT_SEQUENCE
+SELECT NEXT VALUE FOR v;
+
+--echo #
+--echo # MDEV-24018: SIGSEGV in Item_func_nextval::update_table on SELECT SETVAL
+--echo #
+--error ER_NOT_SEQUENCE
+SELECT SETVAL (v,0);
+
+UNLOCK TABLES;
+DROP VIEW v;
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 e16ce76fed9..c839dd6b289 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
@@ -51,9 +51,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.03
-2 Record_2 501 1.25
-3 Record_3 210 0.53
+1 Record_1 100011 250.027
+2 Record_2 501 1.2525
+3 Record_3 210 0.525
connect test_con2, localhost, root,,;
connection test_con2;
## Verifying session & global value of variable ##
@@ -69,11 +69,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.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
+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
6 Record_6 210 0.525
## Dropping table t1 ##
drop table t1;
diff --git a/mysql-test/suite/sys_vars/r/innodb_doublewrite_batch_size_basic.result b/mysql-test/suite/sys_vars/r/innodb_doublewrite_batch_size_basic.result
deleted file mode 100644
index cec90ea8950..00000000000
--- a/mysql-test/suite/sys_vars/r/innodb_doublewrite_batch_size_basic.result
+++ /dev/null
@@ -1,24 +0,0 @@
-select @@global.innodb_doublewrite_batch_size between 1 and 127;
-@@global.innodb_doublewrite_batch_size between 1 and 127
-1
-select @@global.innodb_doublewrite_batch_size;
-@@global.innodb_doublewrite_batch_size
-120
-select @@session.innodb_doublewrite_batch_size;
-ERROR HY000: Variable 'innodb_doublewrite_batch_size' is a GLOBAL variable
-show global variables like 'innodb_doublewrite_batch_size';
-Variable_name Value
-innodb_doublewrite_batch_size 120
-show session variables like 'innodb_doublewrite_batch_size';
-Variable_name Value
-innodb_doublewrite_batch_size 120
-select * from information_schema.global_variables where variable_name='innodb_doublewrite_batch_size';
-VARIABLE_NAME VARIABLE_VALUE
-INNODB_DOUBLEWRITE_BATCH_SIZE 120
-select * from information_schema.session_variables where variable_name='innodb_doublewrite_batch_size';
-VARIABLE_NAME VARIABLE_VALUE
-INNODB_DOUBLEWRITE_BATCH_SIZE 120
-set global innodb_doublewrite_batch_size=1;
-ERROR HY000: Variable 'innodb_doublewrite_batch_size' is a read only variable
-set @@session.innodb_doublewrite_batch_size='some';
-ERROR HY000: Variable 'innodb_doublewrite_batch_size' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
index 20b619972dd..e83f528a94e 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_basic.result
@@ -17,13 +17,13 @@ SET @@global.innodb_max_dirty_pages_pct = 0;
SET @@global.innodb_max_dirty_pages_pct = DEFAULT;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
-75.000000
+90.000000
'#---------------------FN_DYNVARS_046_02-------------------------#'
SET innodb_max_dirty_pages_pct = 1;
ERROR HY000: Variable 'innodb_max_dirty_pages_pct' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@innodb_max_dirty_pages_pct;
@@innodb_max_dirty_pages_pct
-75.000000
+90.000000
SELECT local.innodb_max_dirty_pages_pct;
ERROR 42S02: Unknown table 'local' in field list
SET global innodb_max_dirty_pages_pct = 0;
diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
index 8b68f182789..43cdf17ee27 100644
--- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result
@@ -1,26 +1,28 @@
+SET @innodb_max_dirty_pages_pct_lwm = @@global.innodb_max_dirty_pages_pct_lwm;
SET @innodb_max_dirty_pages_pct = @@global.innodb_max_dirty_pages_pct;
'#--------------------FN_DYNVARS_044_02-------------------------#'
+SET @@global.innodb_max_dirty_pages_pct_lwm = 0;
SET @@global.innodb_max_dirty_pages_pct = 80;
-'connect (con1,localhost,root,,,,)'
+SET @@global.innodb_max_dirty_pages_pct_lwm = 80;
connect con1,localhost,root,,,,;
-'connection con1'
connection con1;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
80.000000
SET @@global.innodb_max_dirty_pages_pct = 70;
-'connect (con2,localhost,root,,,,)'
+Warnings:
+Warning 1210 innodb_max_dirty_pages_pct cannot be set lower than innodb_max_dirty_pages_pct_lwm.
+Warning 1210 Lowering innodb_max_dirty_page_pct_lwm to 70.000000
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
+@@global.innodb_max_dirty_pages_pct_lwm
+70.000000
connect con2,localhost,root,,,,;
-'connection con2'
connection con2;
SELECT @@global.innodb_max_dirty_pages_pct;
@@global.innodb_max_dirty_pages_pct
70.000000
-'connection default'
connection default;
-'disconnect con2'
disconnect con2;
-'disconnect con1'
disconnect con1;
SET @@global.innodb_max_dirty_pages_pct = @innodb_max_dirty_pages_pct;
'#--------------------FN_DYNVARS_044_02-------------------------#'
@@ -85,6 +87,22 @@ b CHAR(200)
) ENGINE = INNODB;
'---Check when innodb_max_dirty_pages_pct is 10---'
SET @@global.innodb_max_dirty_pages_pct = 10;
+Warnings:
+Warning 1210 innodb_max_dirty_pages_pct cannot be set lower than innodb_max_dirty_pages_pct_lwm.
+Warning 1210 Lowering innodb_max_dirty_page_pct_lwm to 10.000000
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
+@@global.innodb_max_dirty_pages_pct_lwm
+10.000000
+SET GLOBAL innodb_max_dirty_pages_pct_lwm = 15;
+Warnings:
+Warning 1210 innodb_max_dirty_pages_pct_lwm cannot be set higher than innodb_max_dirty_pages_pct.
+Warning 1210 Setting innodb_max_dirty_page_pct_lwm to 10.000000
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
+@@global.innodb_max_dirty_pages_pct_lwm
+10.000000
+SELECT @@global.innodb_max_dirty_pages_pct;
+@@global.innodb_max_dirty_pages_pct
+10.000000
FLUSH STATUS;
CALL add_until(10);
FLUSH TABLES;
@@ -98,4 +116,6 @@ DROP PROCEDURE add_until;
DROP PROCEDURE check_pct;
DROP FUNCTION dirty_pct;
DROP TABLE t1;
+SET GLOBAL innodb_max_dirty_pages_pct_lwm = 0;
SET @@global.innodb_max_dirty_pages_pct = @innodb_max_dirty_pages_pct;
+SET @@global.innodb_max_dirty_pages_pct_lwm = @innodb_max_dirty_pages_pct_lwm;
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 ec3b39124fe..249d745482a 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,12 @@ 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
+connection master;
+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/session_track_system_variables_basic.result b/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result
index e0f3e210feb..c3f4a4ee4eb 100644
--- a/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result
+++ b/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result
@@ -147,6 +147,8 @@ SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
+# MDEV-22524 SIGABRT in safe_mutex_unlock with session_track_system_variables and max_relay_log_size.
+SET SESSION session_track_system_variables="sql_slave_skip_counter", sql_slave_skip_counter= 0;
# Restoring the original values.
SET @@global.session_track_system_variables = @global_saved_tmp;
# End of tests.
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff
index 2f39a472b99..ea9f47d8f3a 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff
@@ -9,15 +9,6 @@
VARIABLE_COMMENT Number of InnoDB Adaptive Hash Index Partitions (default 8)
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 512
-@@ -73,7 +73,7 @@
- SESSION_VALUE NULL
- DEFAULT_VALUE 64
- VARIABLE_SCOPE GLOBAL
--VARIABLE_TYPE BIGINT UNSIGNED
-+VARIABLE_TYPE INT UNSIGNED
- VARIABLE_COMMENT Data file autoextend increment in megabytes
- NUMERIC_MIN_VALUE 1
- NUMERIC_MAX_VALUE 1000
@@ -85,7 +85,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1
@@ -85,16 +76,7 @@
VARIABLE_COMMENT Percentage of empty space on a data page that can be reserved to make the page compressible.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 75
-@@ -661,7 +661,7 @@
- SESSION_VALUE NULL
- DEFAULT_VALUE 120
- VARIABLE_SCOPE GLOBAL
--VARIABLE_TYPE BIGINT UNSIGNED
-+VARIABLE_TYPE INT UNSIGNED
- VARIABLE_COMMENT Number of pages reserved in doublewrite buffer for batch flushing
- NUMERIC_MIN_VALUE 1
- NUMERIC_MAX_VALUE 127
-@@ -757,7 +757,7 @@
+@@ -745,7 +745,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 600
VARIABLE_SCOPE GLOBAL
@@ -105,15 +87,6 @@
NUMERIC_MAX_VALUE 4294967295
@@ -805,7 +805,7 @@
SESSION_VALUE NULL
- DEFAULT_VALUE 0
- VARIABLE_SCOPE GLOBAL
--VARIABLE_TYPE BIGINT UNSIGNED
-+VARIABLE_TYPE INT UNSIGNED
- VARIABLE_COMMENT Make the first page of the given tablespace dirty.
- NUMERIC_MIN_VALUE 0
- NUMERIC_MAX_VALUE 4294967295
-@@ -817,7 +817,7 @@
- SESSION_VALUE NULL
DEFAULT_VALUE 30
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
@@ -121,7 +94,7 @@
VARIABLE_COMMENT Number of iterations over which the background flushing is averaged.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1000
-@@ -841,7 +841,7 @@
+@@ -829,7 +829,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1
VARIABLE_SCOPE GLOBAL
@@ -130,7 +103,7 @@
VARIABLE_COMMENT Controls the durability/speed trade-off for commits. Set to 0 (write and flush redo log to disk only once per second), 1 (flush to disk at each commit), 2 (write to log at commit but flush to disk only once per second) or 3 (flush to disk at prepare and at commit, slower and usually redundant). 1 and 3 guarantees that after a crash, committed transactions will not be lost and will be consistent with the binlog and other transactional engines. 2 can get inconsistent and lose transactions if there is a power failure or kernel crash but not if mysqld crashes. 0 has no guarantees in case of crash. 0 and 2 can be faster than 1 or 3.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 3
-@@ -865,7 +865,7 @@
+@@ -853,7 +853,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1
VARIABLE_SCOPE GLOBAL
@@ -139,7 +112,7 @@
VARIABLE_COMMENT Set to 0 (don't flush neighbors from buffer pool), 1 (flush contiguous neighbors from buffer pool) or 2 (flush neighbors from buffer pool), when flushing a block
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 2
-@@ -913,7 +913,7 @@
+@@ -901,7 +901,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
@@ -148,7 +121,7 @@
VARIABLE_COMMENT Helps to save your data in case the disk image of the database becomes corrupt. Value 5 can return bogus data, and 6 can permanently corrupt data.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 6
-@@ -937,7 +937,7 @@
+@@ -925,7 +925,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 8000000
VARIABLE_SCOPE GLOBAL
@@ -157,7 +130,7 @@
VARIABLE_COMMENT InnoDB Fulltext search cache size in bytes
NUMERIC_MIN_VALUE 1600000
NUMERIC_MAX_VALUE 80000000
-@@ -973,7 +973,7 @@
+@@ -961,7 +961,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 84
VARIABLE_SCOPE GLOBAL
@@ -166,7 +139,7 @@
VARIABLE_COMMENT InnoDB Fulltext search maximum token size in characters
NUMERIC_MIN_VALUE 10
NUMERIC_MAX_VALUE 84
-@@ -985,7 +985,7 @@
+@@ -973,7 +973,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 3
VARIABLE_SCOPE GLOBAL
@@ -175,7 +148,7 @@
VARIABLE_COMMENT InnoDB Fulltext search minimum token size in characters
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 16
-@@ -997,7 +997,7 @@
+@@ -985,7 +985,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 2000
VARIABLE_SCOPE GLOBAL
@@ -184,7 +157,7 @@
VARIABLE_COMMENT InnoDB Fulltext search number of words to optimize for each optimize table call
NUMERIC_MIN_VALUE 1000
NUMERIC_MAX_VALUE 10000
-@@ -1009,10 +1009,10 @@
+@@ -997,10 +997,10 @@
SESSION_VALUE NULL
DEFAULT_VALUE 2000000000
VARIABLE_SCOPE GLOBAL
@@ -197,7 +170,7 @@
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -1033,7 +1033,7 @@
+@@ -1021,7 +1021,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 2
VARIABLE_SCOPE GLOBAL
@@ -206,7 +179,7 @@
VARIABLE_COMMENT InnoDB Fulltext search parallel sort degree, will round up to nearest power of 2 number
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 16
-@@ -1045,7 +1045,7 @@
+@@ -1033,7 +1033,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 640000000
VARIABLE_SCOPE GLOBAL
@@ -215,7 +188,7 @@
VARIABLE_COMMENT Total memory allocated for InnoDB Fulltext Search cache
NUMERIC_MIN_VALUE 32000000
NUMERIC_MAX_VALUE 1600000000
-@@ -1069,7 +1069,7 @@
+@@ -1057,7 +1057,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
@@ -224,7 +197,7 @@
VARIABLE_COMMENT Up to what percentage of dirty pages should be flushed when innodb finds it has spare resources to do so.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 100
-@@ -1105,22 +1105,22 @@
+@@ -1093,22 +1093,22 @@
SESSION_VALUE NULL
DEFAULT_VALUE 200
VARIABLE_SCOPE GLOBAL
@@ -252,7 +225,7 @@
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
-@@ -1165,7 +1165,7 @@
+@@ -1153,7 +1153,7 @@
SESSION_VALUE 50
DEFAULT_VALUE 50
VARIABLE_SCOPE SESSION
@@ -261,7 +234,7 @@
VARIABLE_COMMENT Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1073741824
-@@ -1177,10 +1177,10 @@
+@@ -1165,10 +1165,10 @@
SESSION_VALUE NULL
DEFAULT_VALUE 16777216
VARIABLE_SCOPE GLOBAL
@@ -274,7 +247,7 @@
NUMERIC_BLOCK_SIZE 1024
ENUM_VALUE_LIST NULL
READ_ONLY YES
-@@ -1225,7 +1225,7 @@
+@@ -1213,7 +1213,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1
VARIABLE_SCOPE GLOBAL
@@ -283,7 +256,7 @@
VARIABLE_COMMENT Deprecated parameter with no effect.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 100
-@@ -1273,7 +1273,7 @@
+@@ -1261,7 +1261,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 8192
VARIABLE_SCOPE GLOBAL
@@ -292,6 +265,19 @@
VARIABLE_COMMENT Redo log write ahead unit size to avoid read-on-write, it should match the OS cache block IO size
NUMERIC_MIN_VALUE 512
NUMERIC_MAX_VALUE 16384
+@@ -1273,10 +1273,10 @@
+ SESSION_VALUE NULL
+ DEFAULT_VALUE 100
+ VARIABLE_SCOPE GLOBAL
+-VARIABLE_TYPE BIGINT UNSIGNED
++VARIABLE_TYPE INT UNSIGNED
+ VARIABLE_COMMENT How many pages to flush on LRU eviction
+ NUMERIC_MIN_VALUE 1
+-NUMERIC_MAX_VALUE 18446744073709551615
++NUMERIC_MAX_VALUE 4294967295
+ NUMERIC_BLOCK_SIZE 0
+ ENUM_VALUE_LIST NULL
+ READ_ONLY NO
@@ -1285,10 +1285,10 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1024
@@ -394,15 +380,6 @@
VARIABLE_COMMENT Number of background read I/O threads in InnoDB.
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 64
-@@ -1657,7 +1657,7 @@
- SESSION_VALUE NULL
- DEFAULT_VALUE 0
- VARIABLE_SCOPE GLOBAL
--VARIABLE_TYPE BIGINT UNSIGNED
-+VARIABLE_TYPE INT UNSIGNED
- VARIABLE_COMMENT An InnoDB page number.
- NUMERIC_MIN_VALUE 0
- NUMERIC_MAX_VALUE 4294967295
@@ -1705,7 +1705,7 @@
SESSION_VALUE NULL
DEFAULT_VALUE 1048576
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 206a58f269f..2fe4fe028af 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -61,7 +61,7 @@ VARIABLE_NAME INNODB_AUTOEXTEND_INCREMENT
SESSION_VALUE NULL
DEFAULT_VALUE 64
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Data file autoextend increment in megabytes
NUMERIC_MIN_VALUE 1
NUMERIC_MAX_VALUE 1000
@@ -561,18 +561,6 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
COMMAND_LINE_ARGUMENT NONE
-VARIABLE_NAME INNODB_DOUBLEWRITE_BATCH_SIZE
-SESSION_VALUE NULL
-DEFAULT_VALUE 120
-VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
-VARIABLE_COMMENT Number of pages reserved in doublewrite buffer for batch flushing
-NUMERIC_MIN_VALUE 1
-NUMERIC_MAX_VALUE 127
-NUMERIC_BLOCK_SIZE 0
-ENUM_VALUE_LIST NULL
-READ_ONLY YES
-COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_ENCRYPTION_ROTATE_KEY_AGE
SESSION_VALUE NULL
DEFAULT_VALUE 1
@@ -697,7 +685,7 @@ VARIABLE_NAME INNODB_FIL_MAKE_PAGE_DIRTY_DEBUG
SESSION_VALUE NULL
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Make the first page of the given tablespace dirty.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
@@ -1101,9 +1089,21 @@ NUMERIC_BLOCK_SIZE 512
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME INNODB_LRU_FLUSH_SIZE
+SESSION_VALUE NULL
+DEFAULT_VALUE 32
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_COMMENT How many pages to flush on LRU eviction
+NUMERIC_MIN_VALUE 1
+NUMERIC_MAX_VALUE 18446744073709551615
+NUMERIC_BLOCK_SIZE 0
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_LRU_SCAN_DEPTH
SESSION_VALUE NULL
-DEFAULT_VALUE 1024
+DEFAULT_VALUE 1536
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT How deep to scan LRU to keep it clean
@@ -1127,7 +1127,7 @@ READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_MAX_DIRTY_PAGES_PCT
SESSION_VALUE NULL
-DEFAULT_VALUE 75.000000
+DEFAULT_VALUE 90.000000
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE DOUBLE
VARIABLE_COMMENT Percentage of dirty pages allowed in bufferpool.
@@ -1173,6 +1173,18 @@ NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
+VARIABLE_NAME INNODB_MAX_PURGE_LAG_WAIT
+SESSION_VALUE NULL
+DEFAULT_VALUE 4294967295
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE INT UNSIGNED
+VARIABLE_COMMENT Wait until History list length is below the specified limit
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_BLOCK_SIZE 0
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_MAX_UNDO_LOG_SIZE
SESSION_VALUE NULL
DEFAULT_VALUE 10485760
@@ -1453,7 +1465,7 @@ VARIABLE_NAME INNODB_SAVED_PAGE_NUMBER_DEBUG
SESSION_VALUE NULL
DEFAULT_VALUE 0
VARIABLE_SCOPE GLOBAL
-VARIABLE_TYPE BIGINT UNSIGNED
+VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT An InnoDB page number.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 4294967295
diff --git a/mysql-test/suite/sys_vars/r/wsrep_cluster_address_basic.result b/mysql-test/suite/sys_vars/r/wsrep_cluster_address_basic.result
index 8497e220523..4e4893532fb 100644
--- a/mysql-test/suite/sys_vars/r/wsrep_cluster_address_basic.result
+++ b/mysql-test/suite/sys_vars/r/wsrep_cluster_address_basic.result
@@ -1,7 +1,6 @@
#
# wsrep_cluster_address
#
-call mtr.add_suppression("safe_mutex: Found wrong usage of mutex.*");
# save the initial value
SET @wsrep_cluster_address_global_saved = @@global.wsrep_cluster_address;
# default
diff --git a/mysql-test/suite/sys_vars/t/innodb_doublewrite_batch_size_basic.test b/mysql-test/suite/sys_vars/t/innodb_doublewrite_batch_size_basic.test
deleted file mode 100644
index 5e9104b5335..00000000000
--- a/mysql-test/suite/sys_vars/t/innodb_doublewrite_batch_size_basic.test
+++ /dev/null
@@ -1,24 +0,0 @@
---source include/have_innodb.inc
---source include/have_debug.inc
-
-#
-# exists as global only
-#
-select @@global.innodb_doublewrite_batch_size between 1 and 127;
-select @@global.innodb_doublewrite_batch_size;
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-select @@session.innodb_doublewrite_batch_size;
-show global variables like 'innodb_doublewrite_batch_size';
-show session variables like 'innodb_doublewrite_batch_size';
---disable_warnings
-select * from information_schema.global_variables where variable_name='innodb_doublewrite_batch_size';
-select * from information_schema.session_variables where variable_name='innodb_doublewrite_batch_size';
---enable_warnings
-
-#
-# show that it's read-only
-#
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-set global innodb_doublewrite_batch_size=1;
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-set @@session.innodb_doublewrite_batch_size='some';
diff --git a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test
index c7a9e567e69..0720aca65b9 100644
--- a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test
+++ b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test
@@ -25,6 +25,7 @@
--source include/have_innodb.inc
# safe initial value
+SET @innodb_max_dirty_pages_pct_lwm = @@global.innodb_max_dirty_pages_pct_lwm;
SET @innodb_max_dirty_pages_pct = @@global.innodb_max_dirty_pages_pct;
--echo '#--------------------FN_DYNVARS_044_02-------------------------#'
@@ -32,23 +33,19 @@ SET @innodb_max_dirty_pages_pct = @@global.innodb_max_dirty_pages_pct;
# Check if setting innodb_max_dirty_pages_pct is changed in new connection #
############################################################################
+SET @@global.innodb_max_dirty_pages_pct_lwm = 0;
SET @@global.innodb_max_dirty_pages_pct = 80;
---echo 'connect (con1,localhost,root,,,,)'
+SET @@global.innodb_max_dirty_pages_pct_lwm = 80;
connect (con1,localhost,root,,,,);
---echo 'connection con1'
connection con1;
SELECT @@global.innodb_max_dirty_pages_pct;
SET @@global.innodb_max_dirty_pages_pct = 70;
---echo 'connect (con2,localhost,root,,,,)'
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
connect (con2,localhost,root,,,,);
---echo 'connection con2'
connection con2;
SELECT @@global.innodb_max_dirty_pages_pct;
---echo 'connection default'
connection default;
---echo 'disconnect con2'
disconnect con2;
---echo 'disconnect con1'
disconnect con1;
# restore initial value
SET @@global.innodb_max_dirty_pages_pct = @innodb_max_dirty_pages_pct;
@@ -138,6 +135,10 @@ b CHAR(200)
#==========================================================
SET @@global.innodb_max_dirty_pages_pct = 10;
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
+SET GLOBAL innodb_max_dirty_pages_pct_lwm = 15;
+SELECT @@global.innodb_max_dirty_pages_pct_lwm;
+SELECT @@global.innodb_max_dirty_pages_pct;
FLUSH STATUS;
@@ -164,7 +165,9 @@ DROP FUNCTION dirty_pct;
DROP TABLE t1;
# restore initial value
+SET GLOBAL innodb_max_dirty_pages_pct_lwm = 0;
SET @@global.innodb_max_dirty_pages_pct = @innodb_max_dirty_pages_pct;
+SET @@global.innodb_max_dirty_pages_pct_lwm = @innodb_max_dirty_pages_pct_lwm;
##################################################################
# End of functionality Testing for innodb_max_dirty_pages_pct #
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 f8cbc54fc70..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,7 +29,13 @@
###############################################################################
source include/master-slave.inc;
-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
@@ -66,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;
@@ -87,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/session_track_system_variables_basic.test b/mysql-test/suite/sys_vars/t/session_track_system_variables_basic.test
index 20f0cd6cf17..8c1d5dd6546 100644
--- a/mysql-test/suite/sys_vars/t/session_track_system_variables_basic.test
+++ b/mysql-test/suite/sys_vars/t/session_track_system_variables_basic.test
@@ -119,6 +119,8 @@ SELECT @@global.session_track_system_variables;
SELECT @@session.session_track_system_variables;
--echo
+--echo # MDEV-22524 SIGABRT in safe_mutex_unlock with session_track_system_variables and max_relay_log_size.
+SET SESSION session_track_system_variables="sql_slave_skip_counter", sql_slave_skip_counter= 0;
--echo # Restoring the original values.
SET @@global.session_track_system_variables = @global_saved_tmp;
diff --git a/mysql-test/suite/sys_vars/t/wsrep_cluster_address_basic.test b/mysql-test/suite/sys_vars/t/wsrep_cluster_address_basic.test
index 136c0745e42..6e0767ce853 100644
--- a/mysql-test/suite/sys_vars/t/wsrep_cluster_address_basic.test
+++ b/mysql-test/suite/sys_vars/t/wsrep_cluster_address_basic.test
@@ -4,8 +4,6 @@
--echo # wsrep_cluster_address
--echo #
-call mtr.add_suppression("safe_mutex: Found wrong usage of mutex.*");
-
--echo # save the initial value
SET @wsrep_cluster_address_global_saved = @@global.wsrep_cluster_address;
diff --git a/mysql-test/suite/vcol/r/not_supported.result b/mysql-test/suite/vcol/r/not_supported.result
index c524234e7e5..c804cf220d2 100644
--- a/mysql-test/suite/vcol/r/not_supported.result
+++ b/mysql-test/suite/vcol/r/not_supported.result
@@ -29,7 +29,7 @@ set time_zone='+1:00';
flush tables;
select * from t1;
a b v
-1 2 0.3333000000000000000
+1 2 0.3333333330000000000
select * from t8;
a b v
1234567890 2 2009-02-14 00:31:30
diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result
index 3c15f84c18b..5badb4b4a22 100644
--- a/mysql-test/suite/versioning/r/create.result
+++ b/mysql-test/suite/versioning/r/create.result
@@ -536,3 +536,59 @@ with system versioning
select 1 as x;
ERROR HY000: Table `t1` must have at least one versioned column
drop tables t0, t1, t2, t3;
+#
+# MDEV-23968 CREATE TEMPORARY TABLE .. LIKE (system versioned table) returns error if unique index is defined in the table
+#
+create table t1 (id int primary key, index(row_start)) with system versioning;
+ERROR 42000: Key column 'row_start' doesn't exist in table
+create table t1 (id int primary key, index(row_end)) with system versioning;
+ERROR 42000: Key column 'row_end' doesn't exist in table
+create table t1 (id int, primary key(id, row_end, row_end)) with system versioning;
+ERROR 42000: Key column 'row_end' doesn't exist in table
+create table t1 (id int primary key) with system versioning;
+create temporary table t2 like t1;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.t2`
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+show create table t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `id` int(11) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+drop temporary table t2;
+create or replace table t1 (
+a int,
+row_start timestamp(6) as row start,
+row_end timestamp(6) as row end,
+period for system_time (row_start, row_end),
+index(row_start),
+index(row_end),
+primary key(row_end, a, row_start),
+index(row_end, row_start, a)) with system versioning;
+create temporary table t2 like t1;
+Warnings:
+Warning 1105 System versioning is stripped from temporary `test.t2`
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `row_start` timestamp(6) GENERATED ALWAYS AS ROW START,
+ `row_end` timestamp(6) GENERATED ALWAYS AS ROW END,
+ PRIMARY KEY (`row_end`,`a`,`row_start`),
+ KEY `row_start` (`row_start`),
+ KEY `row_end` (`row_end`),
+ KEY `row_end_2` (`row_end`,`row_start`,`a`),
+ PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
+show create table t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `a` int(11) NOT NULL
+) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
+drop temporary table t2;
+drop table t1;
diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result
index 7194b9abcf6..4c0867d579b 100644
--- a/mysql-test/suite/versioning/r/cte.result
+++ b/mysql-test/suite/versioning/r/cte.result
@@ -38,7 +38,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION e ALL NULL NULL NULL NULL 4 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` where `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+Note 1003 with ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
select row_start into @ts_2 from emp where name="john";
explain extended /* All report to 'Bill' */
with recursive
@@ -62,7 +62,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
/* All report to 'Bill' */
with recursive
ancestors
@@ -103,7 +103,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `ancestors`.`emp_id` AS `emp_id`,`ancestors`.`name` AS `name`,`ancestors`.`mgr` AS `mgr`,`ancestors`.`salary` AS `salary` from `ancestors`
with recursive
ancestors
as
@@ -144,7 +144,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 RECURSIVE UNION <derived2> ref key0 key0 5 test.e.mgr 2 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME ALL `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` FOR SYSTEM_TIME ALL semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+Note 1003 with recursive ancestors as (/* select#2 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` where `test`.`e`.`name` = 'bill' and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1` union /* select#3 */ select `test`.`e`.`emp_id` AS `emp_id`,`test`.`e`.`name` AS `name`,`test`.`e`.`mgr` AS `mgr`,`test`.`e`.`salary` AS `salary` from `test`.`emp` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts_1` `e` join `ancestors` `a` where `a`.`emp_id` = `test`.`e`.`mgr` and `test`.`e`.`row_end` > @`ts_1` and `test`.`e`.`row_start` <= @`ts_1`)/* select#1 */ select `test`.`emp`.`name` AS `name` from `test`.`emp` semi join (`ancestors`) where `ancestors`.`emp_id` = `test`.`emp`.`emp_id` and `test`.`emp`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
with recursive
ancestors
as
diff --git a/mysql-test/suite/versioning/r/derived.result b/mysql-test/suite/versioning/r/derived.result
index 5b8eee4ab4a..700c92a8d5c 100644
--- a/mysql-test/suite/versioning/r/derived.result
+++ b/mysql-test/suite/versioning/r/derived.result
@@ -211,12 +211,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Query A:
-Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Query B:
-Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP current_timestamp(6) where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t2`.`row_start` <= <cache>(current_timestamp(6)) and `test`.`t1`.`row_end` > <cache>(current_timestamp(6)) and `test`.`t1`.`row_start` <= <cache>(current_timestamp(6))
Fine result: queries A and B are equal.
## LEFT JOIN: t1, t2 versioned
select * from (
diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result
index 3489909e925..6df18403ee3 100644
--- a/mysql-test/suite/versioning/r/select.result
+++ b/mysql-test/suite/versioning/r/select.result
@@ -155,21 +155,21 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
+Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x)
for system_time as of timestamp @t0 as t;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL left join `test`.`t2` FOR SYSTEM_TIME ALL on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
+Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` left join `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`
explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x)
for system_time as of timestamp @t0 as t;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME ALL left join `test`.`t1` FOR SYSTEM_TIME ALL on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`) where `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`
+Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` left join `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`t0` on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`) where `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`
select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x)
for system_time as of timestamp @t0 as t;
IJ2_x1 y1 x2 y2
@@ -329,7 +329,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` FOR SYSTEM_TIME ALL left join (`test`.`t1` FOR SYSTEM_TIME ALL `t2` left join `test`.`t1` FOR SYSTEM_TIME ALL `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t1` `t2` left join `test`.`t1` `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a
2 1
@@ -560,7 +560,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` FOR SYSTEM_TIME ALL on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
+Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999'
drop view v1;
drop table t1, t2, t3, t4;
#
@@ -648,6 +648,27 @@ ERROR 22007: Incorrect date value: 'foo' for column `test`.`t2`.`b` at row 1
drop prepare stmt;
drop procedure pr;
drop table t1, t2;
+#
+# MDEV-23799 CREATE .. SELECT wrong result on join versioned table
+#
+create or replace table x (id Int) with system versioning;
+create or replace table x_p (elementId Int, pkey varchar(20), pvalue varchar(20)) with system versioning;
+insert into x values (1), (2), (3);
+insert into x_p values (1, 'gender', 'male');
+insert into x_p values (2, 'gender', 'female');
+insert into x_p values (3, 'gender', 'male');
+create table tmp1
+select xgender.pvalue as gender, xtitle.pvalue as title
+from x
+left join x_p as xgender on x.id = xgender.elementId and xgender.pkey = 'gender'
+ left join x_p as xtitle on x.id = xtitle.elementId and xtitle.pkey = 'title';
+select * from tmp1;
+gender title
+male NULL
+female NULL
+male NULL
+drop table tmp1;
+drop tables x, x_p;
call verify_trt_dummy(34);
No A B C D
1 1 1 1 1
diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result
index c0b4eac91d9..e8d550cefa6 100644
--- a/mysql-test/suite/versioning/r/trx_id.result
+++ b/mysql-test/suite/versioning/r/trx_id.result
@@ -213,17 +213,17 @@ EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION @ts;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME ALL where trt_trx_sees(`test`.`t1`.`sys_trx_end`,@`ts`) and trt_trx_sees_eq(@`ts`,`test`.`t1`.`sys_trx_start`)
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TRANSACTION @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,@`ts`) and trt_trx_sees_eq(@`ts`,`test`.`t1`.`sys_trx_start`)
EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP @ts;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME ALL where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
EXPLAIN EXTENDED SELECT x FROM t1 FOR SYSTEM_TIME AS OF @ts;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME ALL where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
+Note 1003 select `test`.`t1`.`x` AS `x` from `test`.`t1` FOR SYSTEM_TIME AS OF TIMESTAMP @`ts` where trt_trx_sees(`test`.`t1`.`sys_trx_end`,<cache>(trt_trx_id(@`ts`))) and trt_trx_sees_eq(<cache>(trt_trx_id(@`ts`)),`test`.`t1`.`sys_trx_start`)
DROP TABLE t1;
#
# Testing AS OF with expressions of various kinds and data types
diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result
index e9e74899790..0528edc4bb3 100644
--- a/mysql-test/suite/versioning/r/view.result
+++ b/mysql-test/suite/versioning/r/view.result
@@ -279,3 +279,14 @@ b check_row(row_start, row_end)
drop view v2;
drop view v1;
drop table t1, t2;
+#
+# MDEV-23779 Error upon querying the view, that selecting from versioned table with partitions
+#
+create table t1 (i int) with system versioning
+partition by system_time (partition p0 history, partition pn current);
+create view v1 as select * from t1 partition (pn);
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` PARTITION (`pn`) latin1 latin1_swedish_ci
+drop view v1;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test
index 004943c3be7..1f016fed871 100644
--- a/mysql-test/suite/versioning/t/create.test
+++ b/mysql-test/suite/versioning/t/create.test
@@ -406,3 +406,36 @@ with system versioning
select 1 as x;
drop tables t0, t1, t2, t3;
+
+--echo #
+--echo # MDEV-23968 CREATE TEMPORARY TABLE .. LIKE (system versioned table) returns error if unique index is defined in the table
+--echo #
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+create table t1 (id int primary key, index(row_start)) with system versioning;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+create table t1 (id int primary key, index(row_end)) with system versioning;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+create table t1 (id int, primary key(id, row_end, row_end)) with system versioning;
+create table t1 (id int primary key) with system versioning;
+create temporary table t2 like t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t2;
+drop temporary table t2;
+create or replace table t1 (
+ a int,
+ row_start timestamp(6) as row start,
+ row_end timestamp(6) as row end,
+ period for system_time (row_start, row_end),
+ index(row_start),
+ index(row_end),
+ primary key(row_end, a, row_start),
+ index(row_end, row_start, a)) with system versioning;
+create temporary table t2 like t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t1;
+--replace_result $default_engine DEFAULT_ENGINE
+show create table t2;
+drop temporary table t2;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test
index 6c3e401e1cb..d2615940ac8 100644
--- a/mysql-test/suite/versioning/t/select.test
+++ b/mysql-test/suite/versioning/t/select.test
@@ -452,6 +452,27 @@ drop prepare stmt;
drop procedure pr;
drop table t1, t2;
+--echo #
+--echo # MDEV-23799 CREATE .. SELECT wrong result on join versioned table
+--echo #
+create or replace table x (id Int) with system versioning;
+create or replace table x_p (elementId Int, pkey varchar(20), pvalue varchar(20)) with system versioning;
+
+insert into x values (1), (2), (3);
+insert into x_p values (1, 'gender', 'male');
+insert into x_p values (2, 'gender', 'female');
+insert into x_p values (3, 'gender', 'male');
+
+create table tmp1
+select xgender.pvalue as gender, xtitle.pvalue as title
+from x
+ left join x_p as xgender on x.id = xgender.elementId and xgender.pkey = 'gender'
+ left join x_p as xtitle on x.id = xtitle.elementId and xtitle.pkey = 'title';
+
+select * from tmp1;
+
+drop table tmp1;
+drop tables x, x_p;
call verify_trt_dummy(34);
diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test
index 37676a7fb50..9bb915f7b77 100644
--- a/mysql-test/suite/versioning/t/view.test
+++ b/mysql-test/suite/versioning/t/view.test
@@ -1,5 +1,6 @@
--source suite/versioning/engines.inc
--source suite/versioning/common.inc
+--source include/have_partition.inc
create or replace table t1 (x int) with system versioning;
insert into t1 values (1);
@@ -213,4 +214,16 @@ drop view v2;
drop view v1;
drop table t1, t2;
+--echo #
+--echo # MDEV-23779 Error upon querying the view, that selecting from versioned table with partitions
+--echo #
+create table t1 (i int) with system versioning
+partition by system_time (partition p0 history, partition pn current);
+create view v1 as select * from t1 partition (pn);
+show create view v1;
+
+# cleanup
+drop view v1;
+drop table t1;
+
--source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/wsrep/r/MDEV-23081.result b/mysql-test/suite/wsrep/r/MDEV-23081.result
new file mode 100644
index 00000000000..5d0ad90b030
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/MDEV-23081.result
@@ -0,0 +1,24 @@
+CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
+connect con1, localhost, root;
+SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification";
+SET DEBUG_SYNC = "wsrep_before_commit_order_enter SIGNAL before_commit_order_reached_1 WAIT_FOR continue_before_commit_order_1";
+INSERT INTO t1 VALUES (9);
+connect con_ctrl, localhost, root;
+SET DEBUG_SYNC = "now WAIT_FOR after_certification_reached";
+connect con2, localhost, root;
+SET DEBUG_SYNC = "wsrep_before_commit_order_enter SIGNAL before_commit_order_reached_2 WAIT_FOR continue_before_commit_order_2";
+INSERT INTO t1 VALUES (10);
+connection con_ctrl;
+SET DEBUG_SYNC = "now WAIT_FOR before_commit_order_reached_2";
+SET DEBUG_SYNC = "now SIGNAL continue_after_certification";
+SET DEBUG_SYNC = "now WAIT_FOR before_commit_order_reached_1";
+connection default;
+# Kill the server
+XA RECOVER;
+formatID gtrid_length bqual_length data
+disconnect con1;
+disconnect con2;
+disconnect con_ctrl;
+connection default;
+DROP TABLE t1;
+CALL mtr.add_suppression("You need to use --log-bin to make --binlog-format work");
diff --git a/mysql-test/suite/wsrep/r/mdev_22681.result b/mysql-test/suite/wsrep/r/mdev_22681.result
new file mode 100644
index 00000000000..ecce324ead6
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/mdev_22681.result
@@ -0,0 +1,3 @@
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 ENGINE=InnoDB AS SELECT 1 AS b';
+DROP TABLE t1;
diff --git a/mysql-test/suite/wsrep/r/variables.result b/mysql-test/suite/wsrep/r/variables.result
index 1ff221f1459..a9988fd1628 100644
--- a/mysql-test/suite/wsrep/r/variables.result
+++ b/mysql-test/suite/wsrep/r/variables.result
@@ -1,3 +1,4 @@
+call mtr.add_suppression("WSREP: Initial position was provided by configuration or SST, avoiding override");
SET @wsrep_provider_options_saved= @@global.wsrep_provider_options;
SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address;
@@ -48,6 +49,8 @@ wsrep_flow_control_paused_ns #
wsrep_flow_control_paused #
wsrep_flow_control_sent #
wsrep_flow_control_recv #
+wsrep_flow_control_active #
+wsrep_flow_control_requested #
wsrep_cert_deps_distance #
wsrep_apply_oooe #
wsrep_apply_oool #
@@ -109,6 +112,8 @@ wsrep_flow_control_paused_ns #
wsrep_flow_control_paused #
wsrep_flow_control_sent #
wsrep_flow_control_recv #
+wsrep_flow_control_active #
+wsrep_flow_control_requested #
wsrep_cert_deps_distance #
wsrep_apply_oooe #
wsrep_apply_oool #
diff --git a/mysql-test/suite/wsrep/r/variables_debug.result b/mysql-test/suite/wsrep/r/variables_debug.result
new file mode 100644
index 00000000000..886325acf53
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/variables_debug.result
@@ -0,0 +1,278 @@
+call mtr.add_suppression("WSREP: Initial position was provided by configuration or SST, avoiding override");
+SET @wsrep_provider_options_saved= @@global.wsrep_provider_options;
+SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address;
+
+# MDEV#5534: mysql_tzinfo_to_sql generates wrong query
+#
+# Testing wsrep_replicate_myisam variable.
+SELECT @@session.wsrep_replicate_myisam;
+ERROR HY000: Variable 'wsrep_replicate_myisam' is a GLOBAL variable
+SELECT @@global.wsrep_replicate_myisam;
+@@global.wsrep_replicate_myisam
+0
+SET SESSION wsrep_replicate_myisam= ON;
+ERROR HY000: Variable 'wsrep_replicate_myisam' is a GLOBAL variable and should be set with SET GLOBAL
+SET GLOBAL wsrep_replicate_myisam= ON;
+SET GLOBAL wsrep_replicate_myisam= OFF;
+SET GLOBAL wsrep_provider=none;
+#
+# MDEV#5790: SHOW GLOBAL STATUS LIKE does not show the correct list of
+# variables when using "_"
+#
+CALL mtr.add_suppression("WSREP: Could not open saved state file for reading.*");
+SHOW GLOBAL STATUS LIKE 'wsrep%';
+Variable_name Value
+wsrep_local_state_uuid #
+wsrep_protocol_version #
+wsrep_last_committed #
+wsrep_replicated #
+wsrep_replicated_bytes #
+wsrep_repl_keys #
+wsrep_repl_keys_bytes #
+wsrep_repl_data_bytes #
+wsrep_repl_other_bytes #
+wsrep_received #
+wsrep_received_bytes #
+wsrep_local_commits #
+wsrep_local_cert_failures #
+wsrep_local_replays #
+wsrep_local_send_queue #
+wsrep_local_send_queue_max #
+wsrep_local_send_queue_min #
+wsrep_local_send_queue_avg #
+wsrep_local_recv_queue #
+wsrep_local_recv_queue_max #
+wsrep_local_recv_queue_min #
+wsrep_local_recv_queue_avg #
+wsrep_local_cached_downto #
+wsrep_flow_control_paused_ns #
+wsrep_flow_control_paused #
+wsrep_flow_control_sent #
+wsrep_flow_control_recv #
+wsrep_flow_control_active #
+wsrep_flow_control_requested #
+wsrep_cert_deps_distance #
+wsrep_apply_oooe #
+wsrep_apply_oool #
+wsrep_apply_window #
+wsrep_commit_oooe #
+wsrep_commit_oool #
+wsrep_commit_window #
+wsrep_local_state #
+wsrep_local_state_comment #
+wsrep_cert_index_size #
+wsrep_causal_reads #
+wsrep_cert_interval #
+wsrep_open_transactions #
+wsrep_open_connections #
+wsrep_incoming_addresses #
+wsrep_debug_sync_waiters #
+wsrep_applier_thread_count #
+wsrep_cluster_capabilities #
+wsrep_cluster_conf_id #
+wsrep_cluster_size #
+wsrep_cluster_state_uuid #
+wsrep_cluster_status #
+wsrep_connected #
+wsrep_local_bf_aborts #
+wsrep_local_index #
+wsrep_provider_capabilities #
+wsrep_provider_name #
+wsrep_provider_vendor #
+wsrep_provider_version #
+wsrep_ready #
+wsrep_rollbacker_thread_count #
+wsrep_thread_count #
+
+SHOW GLOBAL STATUS LIKE 'wsrep_%';
+Variable_name Value
+wsrep_local_state_uuid #
+wsrep_protocol_version #
+wsrep_last_committed #
+wsrep_replicated #
+wsrep_replicated_bytes #
+wsrep_repl_keys #
+wsrep_repl_keys_bytes #
+wsrep_repl_data_bytes #
+wsrep_repl_other_bytes #
+wsrep_received #
+wsrep_received_bytes #
+wsrep_local_commits #
+wsrep_local_cert_failures #
+wsrep_local_replays #
+wsrep_local_send_queue #
+wsrep_local_send_queue_max #
+wsrep_local_send_queue_min #
+wsrep_local_send_queue_avg #
+wsrep_local_recv_queue #
+wsrep_local_recv_queue_max #
+wsrep_local_recv_queue_min #
+wsrep_local_recv_queue_avg #
+wsrep_local_cached_downto #
+wsrep_flow_control_paused_ns #
+wsrep_flow_control_paused #
+wsrep_flow_control_sent #
+wsrep_flow_control_recv #
+wsrep_flow_control_active #
+wsrep_flow_control_requested #
+wsrep_cert_deps_distance #
+wsrep_apply_oooe #
+wsrep_apply_oool #
+wsrep_apply_window #
+wsrep_commit_oooe #
+wsrep_commit_oool #
+wsrep_commit_window #
+wsrep_local_state #
+wsrep_local_state_comment #
+wsrep_cert_index_size #
+wsrep_causal_reads #
+wsrep_cert_interval #
+wsrep_open_transactions #
+wsrep_open_connections #
+wsrep_incoming_addresses #
+wsrep_debug_sync_waiters #
+wsrep_applier_thread_count #
+wsrep_cluster_capabilities #
+wsrep_cluster_conf_id #
+wsrep_cluster_size #
+wsrep_cluster_state_uuid #
+wsrep_cluster_status #
+wsrep_connected #
+wsrep_local_bf_aborts #
+wsrep_local_index #
+wsrep_provider_capabilities #
+wsrep_provider_name #
+wsrep_provider_vendor #
+wsrep_provider_version #
+wsrep_ready #
+wsrep_rollbacker_thread_count #
+wsrep_thread_count #
+SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';
+Variable_name Value
+wsrep_local_state_comment #
+# Should show nothing.
+SHOW STATUS LIKE 'x';
+Variable_name Value
+SET GLOBAL wsrep_provider=none;
+
+SHOW STATUS LIKE 'wsrep_local_state_uuid';
+Variable_name Value
+wsrep_local_state_uuid #
+
+SHOW STATUS LIKE 'wsrep_last_committed';
+Variable_name Value
+wsrep_last_committed #
+SET GLOBAL wsrep_provider=none;
+
+#
+# MDEV#6206: wsrep_slave_threads subtracts from max_connections
+#
+call mtr.add_suppression("WSREP: Failed to get provider options");
+SELECT @@global.wsrep_provider;
+@@global.wsrep_provider
+libgalera_smm.so
+SELECT @@global.wsrep_slave_threads;
+@@global.wsrep_slave_threads
+1
+SELECT @@global.wsrep_cluster_address;
+@@global.wsrep_cluster_address
+
+SELECT @@global.wsrep_on;
+@@global.wsrep_on
+1
+SHOW STATUS LIKE 'threads_connected';
+Variable_name Value
+Threads_connected 1
+SHOW STATUS LIKE 'wsrep_thread_count';
+Variable_name Value
+wsrep_thread_count 0
+
+SELECT @@global.wsrep_provider;
+@@global.wsrep_provider
+libgalera_smm.so
+SELECT @@global.wsrep_cluster_address;
+@@global.wsrep_cluster_address
+
+SELECT @@global.wsrep_on;
+@@global.wsrep_on
+1
+SHOW STATUS LIKE 'threads_connected';
+Variable_name Value
+Threads_connected 1
+SHOW STATUS LIKE 'wsrep_thread_count';
+Variable_name Value
+wsrep_thread_count 0
+
+# Setting wsrep_cluster_address triggers the creation of
+# applier/rollbacker threads.
+SET GLOBAL wsrep_cluster_address= 'gcomm://';
+# Wait for applier thread to get created 1.
+# Wait for applier thread to get created 2.
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+EXPECT_1
+1
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
+EXPECT_1
+1
+SELECT VARIABLE_VALUE AS EXPECT_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+EXPECT_2
+2
+SELECT @@global.wsrep_provider;
+@@global.wsrep_provider
+libgalera_smm.so
+SELECT @@global.wsrep_cluster_address;
+@@global.wsrep_cluster_address
+gcomm://
+SELECT @@global.wsrep_on;
+@@global.wsrep_on
+1
+SHOW STATUS LIKE 'threads_connected';
+Variable_name Value
+Threads_connected 1
+SHOW STATUS LIKE 'wsrep_thread_count';
+Variable_name Value
+wsrep_thread_count 2
+
+SET @wsrep_slave_threads_saved= @@global.wsrep_slave_threads;
+SET GLOBAL wsrep_slave_threads= 10;
+# Wait for 9 applier threads to get created.
+SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+EXPECT_10
+10
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
+EXPECT_1
+1
+SELECT VARIABLE_VALUE AS EXPECT_11 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+EXPECT_11
+11
+SHOW STATUS LIKE 'threads_connected';
+Variable_name Value
+Threads_connected 1
+set wsrep_on=0;
+set wsrep_on=1;
+create user test@localhost;
+connect con1,localhost,test;
+set auto_increment_increment=10;
+set wsrep_on=0;
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+disconnect con1;
+connection default;
+drop user test@localhost;
+#
+# MDEV#6411: Setting set @@global.wsrep_sst_auth=NULL causes crash
+#
+SET @wsrep_sst_auth_saved= @@global.wsrep_sst_auth;
+SET @@global.wsrep_sst_auth= 'user:pass';
+SELECT @@global.wsrep_sst_auth;
+@@global.wsrep_sst_auth
+********
+SET @@global.wsrep_sst_auth= '';
+SELECT @@global.wsrep_sst_auth;
+@@global.wsrep_sst_auth
+
+SET @@global.wsrep_sst_auth= NULL;
+SELECT @@global.wsrep_sst_auth;
+@@global.wsrep_sst_auth
+NULL
+SET @@global.wsrep_sst_auth= @wsrep_sst_auth_saved;
+# End of test.
diff --git a/mysql-test/suite/wsrep/t/MDEV-23081.cnf b/mysql-test/suite/wsrep/t/MDEV-23081.cnf
new file mode 100644
index 00000000000..489c4385dbd
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23081.cnf
@@ -0,0 +1,9 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=ON
+binlog-format=ROW
+innodb-flush-log-at-trx-commit=1
+wsrep-cluster-address=gcomm://
+wsrep-provider=@ENV.WSREP_PROVIDER
+innodb-autoinc-lock-mode=2
diff --git a/mysql-test/suite/wsrep/t/MDEV-23081.combinations b/mysql-test/suite/wsrep/t/MDEV-23081.combinations
new file mode 100644
index 00000000000..1ce3b45aa1a
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23081.combinations
@@ -0,0 +1,4 @@
+[binlogon]
+log-bin
+
+[binlogoff]
diff --git a/mysql-test/suite/wsrep/t/MDEV-23081.test b/mysql-test/suite/wsrep/t/MDEV-23081.test
new file mode 100644
index 00000000000..04305b22b24
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23081.test
@@ -0,0 +1,57 @@
+#
+# MDEV-23081: Stray XA transactions at startup
+# if node restarts with wsrep_on=OFF
+#
+--source include/have_wsrep.inc
+--source include/have_innodb.inc
+--source include/have_wsrep_provider.inc
+--source include/have_debug_sync.inc
+
+CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
+
+#
+# Execute two inserts on block those after becoming
+# prepared, and before they are committed
+#
+--connect con1, localhost, root
+SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification";
+SET DEBUG_SYNC = "wsrep_before_commit_order_enter SIGNAL before_commit_order_reached_1 WAIT_FOR continue_before_commit_order_1";
+--send INSERT INTO t1 VALUES (9)
+
+--connect con_ctrl, localhost, root
+SET DEBUG_SYNC = "now WAIT_FOR after_certification_reached";
+
+--connect con2, localhost, root
+SET DEBUG_SYNC = "wsrep_before_commit_order_enter SIGNAL before_commit_order_reached_2 WAIT_FOR continue_before_commit_order_2";
+--send INSERT INTO t1 VALUES (10)
+
+--connection con_ctrl
+SET DEBUG_SYNC = "now WAIT_FOR before_commit_order_reached_2";
+SET DEBUG_SYNC = "now SIGNAL continue_after_certification";
+SET DEBUG_SYNC = "now WAIT_FOR before_commit_order_reached_1";
+
+#
+# Kill the server
+#
+--connection default
+--source include/kill_mysqld.inc
+
+#
+# and restart it with wsrep-on=OFF
+#
+let $restart_noprint=2;
+--let $restart_parameters=--wsrep-on=OFF
+--source include/start_mysqld.inc
+
+#
+# Expect no prepared XA transactions to be reported
+#
+XA RECOVER;
+
+--disconnect con1
+--disconnect con2
+--disconnect con_ctrl
+--connection default
+
+DROP TABLE t1;
+CALL mtr.add_suppression("You need to use --log-bin to make --binlog-format work");
diff --git a/mysql-test/suite/wsrep/t/mdev_22681.cnf b/mysql-test/suite/wsrep/t/mdev_22681.cnf
new file mode 100644
index 00000000000..2f310476733
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/mdev_22681.cnf
@@ -0,0 +1,10 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=ON
+log-bin
+binlog-format=ROW
+innodb-flush-log-at-trx-commit=1
+wsrep-cluster-address=gcomm://
+wsrep-provider=@ENV.WSREP_PROVIDER
+innodb-autoinc-lock-mode=2
diff --git a/mysql-test/suite/wsrep/t/mdev_22681.test b/mysql-test/suite/wsrep/t/mdev_22681.test
new file mode 100644
index 00000000000..ce1129c7485
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/mdev_22681.test
@@ -0,0 +1,15 @@
+#
+# MDEV-22681: Server crashes in galera::ReplicatorSMM::CommitOrder::CommitOrder
+# or assertion failed in wsrep::transaction::before_prepare.
+#
+# EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 ENGINE=InnoDB AS SELECT 1 AS b'
+# crashes the server if binlog is on (see mdev_22681.cnf for configuration).
+#
+--source include/have_wsrep.inc
+--source include/have_wsrep_provider.inc
+--source include/have_innodb.inc
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 ENGINE=InnoDB AS SELECT 1 AS b';
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/wsrep/t/variables.cnf b/mysql-test/suite/wsrep/t/variables.cnf
new file mode 100644
index 00000000000..b1c96d2614d
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/variables.cnf
@@ -0,0 +1,7 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=ON
+wsrep-cluster-address=gcomm://
+wsrep-provider=@ENV.WSREP_PROVIDER
+binlog-format=ROW
diff --git a/mysql-test/suite/wsrep/t/variables.opt b/mysql-test/suite/wsrep/t/variables.opt
deleted file mode 100644
index a8b72174076..00000000000
--- a/mysql-test/suite/wsrep/t/variables.opt
+++ /dev/null
@@ -1 +0,0 @@
---wsrep-provider=$WSREP_PROVIDER --wsrep-cluster-address=gcomm:// --wsrep_on=1 --binlog_format=ROW
diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test
index 89b1ff99012..f2c3a0a3b78 100644
--- a/mysql-test/suite/wsrep/t/variables.test
+++ b/mysql-test/suite/wsrep/t/variables.test
@@ -1,6 +1,9 @@
--source include/have_wsrep.inc
--source include/force_restart.inc
--source include/have_innodb.inc
+--source include/galera_have_debug_sync.inc
+
+call mtr.add_suppression("WSREP: Initial position was provided by configuration or SST, avoiding override");
SET @wsrep_provider_options_saved= @@global.wsrep_provider_options;
SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address;
diff --git a/mysql-test/suite/wsrep/t/variables_debug.cnf b/mysql-test/suite/wsrep/t/variables_debug.cnf
new file mode 100644
index 00000000000..b1c96d2614d
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/variables_debug.cnf
@@ -0,0 +1,7 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=ON
+wsrep-cluster-address=gcomm://
+wsrep-provider=@ENV.WSREP_PROVIDER
+binlog-format=ROW
diff --git a/mysql-test/suite/wsrep/t/variables_debug.test b/mysql-test/suite/wsrep/t/variables_debug.test
new file mode 100644
index 00000000000..f2c3a0a3b78
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/variables_debug.test
@@ -0,0 +1,176 @@
+--source include/have_wsrep.inc
+--source include/force_restart.inc
+--source include/have_innodb.inc
+--source include/galera_have_debug_sync.inc
+
+call mtr.add_suppression("WSREP: Initial position was provided by configuration or SST, avoiding override");
+
+SET @wsrep_provider_options_saved= @@global.wsrep_provider_options;
+SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address;
+
+--echo
+--echo # MDEV#5534: mysql_tzinfo_to_sql generates wrong query
+--echo #
+--echo # Testing wsrep_replicate_myisam variable.
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.wsrep_replicate_myisam;
+SELECT @@global.wsrep_replicate_myisam;
+
+--error ER_GLOBAL_VARIABLE
+SET SESSION wsrep_replicate_myisam= ON;
+SET GLOBAL wsrep_replicate_myisam= ON;
+
+# Reset it back.
+SET GLOBAL wsrep_replicate_myisam= OFF;
+SET GLOBAL wsrep_provider=none;
+
+--echo #
+--echo # MDEV#5790: SHOW GLOBAL STATUS LIKE does not show the correct list of
+--echo # variables when using "_"
+--echo #
+
+CALL mtr.add_suppression("WSREP: Could not open saved state file for reading.*");
+
+--disable_query_log
+eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
+--enable_query_log
+
+--replace_column 2 #
+SHOW GLOBAL STATUS LIKE 'wsrep%';
+
+--echo
+--replace_column 2 #
+SHOW GLOBAL STATUS LIKE 'wsrep_%';
+
+--replace_column 2 #
+SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';
+
+--echo # Should show nothing.
+SHOW STATUS LIKE 'x';
+
+# Reset it back.
+SET GLOBAL wsrep_provider=none;
+
+--disable_query_log
+eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
+--enable_query_log
+
+# The following 2 variables are used by mariabackup
+# SST.
+--echo
+--replace_column 2 #
+SHOW STATUS LIKE 'wsrep_local_state_uuid';
+--echo
+--replace_column 2 #
+SHOW STATUS LIKE 'wsrep_last_committed';
+
+# Reset it back.
+SET GLOBAL wsrep_provider=none;
+
+--echo
+--echo #
+--echo # MDEV#6206: wsrep_slave_threads subtracts from max_connections
+--echo #
+call mtr.add_suppression("WSREP: Failed to get provider options");
+
+--disable_query_log
+eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
+--enable_query_log
+
+--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
+SELECT @@global.wsrep_provider;
+SELECT @@global.wsrep_slave_threads;
+SELECT @@global.wsrep_cluster_address;
+SELECT @@global.wsrep_on;
+SHOW STATUS LIKE 'threads_connected';
+SHOW STATUS LIKE 'wsrep_thread_count';
+--echo
+
+--disable_query_log
+eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
+--enable_query_log
+
+--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
+SELECT @@global.wsrep_provider;
+SELECT @@global.wsrep_cluster_address;
+SELECT @@global.wsrep_on;
+SHOW STATUS LIKE 'threads_connected';
+SHOW STATUS LIKE 'wsrep_thread_count';
+--echo
+
+--echo # Setting wsrep_cluster_address triggers the creation of
+--echo # applier/rollbacker threads.
+SET GLOBAL wsrep_cluster_address= 'gcomm://';
+
+--echo # Wait for applier thread to get created 1.
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+--source include/wait_condition.inc
+--echo # Wait for applier thread to get created 2.
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
+--source include/wait_condition.inc
+
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
+SELECT VARIABLE_VALUE AS EXPECT_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+
+--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
+SELECT @@global.wsrep_provider;
+SELECT @@global.wsrep_cluster_address;
+SELECT @@global.wsrep_on;
+SHOW STATUS LIKE 'threads_connected';
+SHOW STATUS LIKE 'wsrep_thread_count';
+--echo
+
+SET @wsrep_slave_threads_saved= @@global.wsrep_slave_threads;
+SET GLOBAL wsrep_slave_threads= 10;
+
+--echo # Wait for 9 applier threads to get created.
+--let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+--source include/wait_condition.inc
+
+SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
+SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
+SELECT VARIABLE_VALUE AS EXPECT_11 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+
+SHOW STATUS LIKE 'threads_connected';
+
+#
+# privileges for wsrep_on
+#
+set wsrep_on=0;
+set wsrep_on=1;
+--source include/wait_until_connected_again.inc
+create user test@localhost;
+connect con1,localhost,test;
+set auto_increment_increment=10;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+set wsrep_on=0;
+disconnect con1;
+connection default;
+drop user test@localhost;
+
+--echo #
+--echo # MDEV#6411: Setting set @@global.wsrep_sst_auth=NULL causes crash
+--echo #
+SET @wsrep_sst_auth_saved= @@global.wsrep_sst_auth;
+SET @@global.wsrep_sst_auth= 'user:pass';
+SELECT @@global.wsrep_sst_auth;
+SET @@global.wsrep_sst_auth= '';
+SELECT @@global.wsrep_sst_auth;
+SET @@global.wsrep_sst_auth= NULL;
+SELECT @@global.wsrep_sst_auth;
+SET @@global.wsrep_sst_auth= @wsrep_sst_auth_saved;
+
+# Reset (for mtr internal checks)
+
+--disable_query_log
+SET GLOBAL wsrep_slave_threads= @wsrep_slave_threads_saved;
+eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
+SET GLOBAL wsrep_cluster_address= @wsrep_cluster_address_saved;
+SET GLOBAL wsrep_provider_options= @wsrep_provider_options_saved;
+--enable_query_log
+
+--source include/galera_wait_ready.inc
+
+--echo # End of test.
diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests
index 8b9c5ecfd6e..71996e68964 100644
--- a/mysql-test/unstable-tests
+++ b/mysql-test/unstable-tests
@@ -23,237 +23,199 @@
#
##############################################################################
#
-# Based on bb-10.5-release 91c3c9efc192ac0ec2ec32fa801bdc0cb236ab5e
-# Thu Aug 6 17:55:22 2020 +0200 - Merge branch '10.4' into 10.5
+# Based on 10.5 8e1e2856f2523c225a81840059e93fa9f61fbacf
-main.alter_table : Modified in 10.5.4
+main.alter_table : Modified in 10.5.7
+main.alter_table_mdev539_maria : MDEV-23922 - Timeout or crash
main.alter_table_trans : MDEV-12084 - timeout
main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result
+main.aria_icp_debug : Added in 10.5.7
main.auth_named_pipe : MDEV-14724 - System error 2
-main.backup_lock : Modified in 10.5.4
-main.backup_stages : MDEV-23401 - Bad file descriptor; modified in 10.5.4
+main.backup_locks : Modified in 10.5.7
+main.backup_stages : MDEV-23401 - Bad file descriptor
main.binary_to_hex : MDEV-20211 - Wrong result
-main.comment_table : Modified in 10.5.4
-main.commit_1innodb : Include file modified in 10.5.4
+main.blackhole : Modified in 10.5.7
+main.bootstrap_innodb : Added in 10.5.7
+main.client_xml : MDEV-24085 - Wrong result
+main.column_compression : MDEV-23954 - Wrong result
main.connect : MDEV-17282 - Wrong result
main.connect-abstract : MDEV-20162 - Could not execute 'check-testcase'
main.connect2 : MDEV-13885 - Server crash
main.count_distinct2 : MDEV-11768 - timeout
-main.create : Modified in 10.5.5
main.create_delayed : MDEV-10605 - failed with timeout
main.create_drop_event : MDEV-16271 - Wrong result
-main.create_drop_function : Modified in 10.5.5
-main.create_drop_view : Modified in 10.5.4
main.create_or_replace : MDEV-22954 - Wrong result
-main.cte_recursive : Modified in 10.5.4
-main.ctype_big5 : Modified in 10.5.4
-main.ctype_binary : Modified in 10.5.4
-main.ctype_cp932 : Modified in 10.5.4
+main.ctype_binary : MDEV-24080 - Data too long for column; include file modified in 10.5.7
+main.ctype_cp1251 : Include file modified in 10.5.7
main.ctype_cp932_binlog_row : MDEV-20540 - Wrong result
main.ctype_cp932_binlog_stm : MDEV-20534 - Wrong result
-main.ctype_dec8 : Added in 10.5.4
-main.ctype_eucjpms : Modified in 10.5.4
-main.ctype_euckr : Modified in 10.5.4
-main.ctype_filename : Modified in 10.5.4
-main.ctype_gb2312 : Modified in 10.5.4
-main.ctype_gbk : Modified in 10.5.4
-main.ctype_ldml : Modified in 10.5.5
-main.ctype_sjis : Modified in 10.5.4
-main.ctype_swe7 : Modified in 10.5.4
-main.ctype_ucs : MDEV-17681 - Data too long for column
+main.ctype_filename : Modified in 10.5.7
+main.ctype_latin1 : Include file modified in 10.5.7
+main.ctype_ucs : MDEV-17681 - Data too long for column; include file modified in 10.5.7
main.ctype_upgrade : MDEV-16945 - Error upon mysql_upgrade
-main.ctype_utf16 : MDEV-10675 - Timeout or extra warnings; modified in 10.5.4
-main.ctype_utf16_uca : Modified in 10.5.4
-main.ctype_utf16le : MDEV-10675 - Timeout or extra warnings; modified in 10.5.4
-main.ctype_utf32 : Modified in 10.5.4
-main.ctype_utf32_uca : Modified in 10.5.4
-main.ctype_utf8 : Modified in 10.5.4
-main.ctype_utf8mb4 : Modified in 10.5.4
-main.ctype_utf8mb4_heap : Include file modified in 10.5.4
-main.ctype_utf8mb4_innodb : MDEV-17744 - Timeout; MDEV-18567 - ASAN use-after-poison; include file modified in 10.5.4
-main.ctype_utf8mb4_myisam : Include file modified in 10.5.4
-main.custom_aggregate_functions : Modified in 10.5.4
+main.ctype_utf16 : MDEV-10675 - Timeout or extra warnings
+main.ctype_utf16le : MDEV-10675 - Timeout or extra warnings
+main.ctype_utf8 : Modified in 10.5.7
+main.ctype_utf8mb4_innodb : MDEV-17744 - Timeout; MDEV-18567 - ASAN use-after-poison
main.debug_sync : MDEV-10607 - internal error
main.delayed : MDEV-20961 - Assertion failure
-main.delete_innodb : Added in 10.5.5
main.derived_cond_pushdown : MDEV-20532 - Floating point differences
main.derived_opt : MDEV-11768 - timeout
main.dirty_close : MDEV-19368 - mysqltest failed but provided no output
main.distinct : MDEV-14194 - Crash
-main.drop : Modified in 10.5.5
main.drop_bad_db_type : MDEV-15676 - Wrong result
-main.drop_combinations : Added in 10.5.4
-main.drop_table_force : Modified in 10.5.5
+main.drop_table_force : Modified in 10.5.7
main.dyncol : MDEV-19455 - Extra warning
+main.errors : Modified in 10.5.7
main.events_2 : MDEV-13277 - Crash
main.events_bugs : MDEV-12892 - Crash
main.events_restart : MDEV-12236 - Server shutdown problem
main.events_slowlog : MDEV-12821 - Wrong result
+main.failed_auth_unixsocket : MDEV-23933 - Access denied
+main.fast_prefix_index_fetch_innodb : Modified in 10.5.7
main.flush : MDEV-19368 - mysqltest failed but provided no output
-main.flush_read_lock : MDEV-22953 - Unknown XID; modified in 10.5.4
+main.flush_block_commit_notembedded : MDEV-23974 - InnoDB error
+main.flush_read_lock : MDEV-22953 - Unknown XID
main.flush_ssl : MDEV-21276 - Aria recovery failure
-main.func_bit : Added in 10.5.4
-main.func_des_encrypt : Modified in 10.5.5
-main.func_gconcat : Modified in 10.5.4
-main.func_json : Modified in 10.5.5
-main.func_math : MDEV-20966 - Wrong error code; modified in 10.5.4
-main.gis : MDEV-13411 - wrong result on P8; modified in 10.5.4
+main.func_gconcat : MDEV-21379 - Valgrind warnings
+main.func_json : Modified in 10.5.7
+main.func_math : MDEV-20966 - Wrong error code; modified in 10.5.7
+main.func_test : Modified in 10.5.7
+main.gis : MDEV-13411 - wrong result on P8
main.gis_notembedded : MDEV-21264 - Wrong result with non-default charset
-main.grant : Modified in 10.5.4
-main.grant5 : Modified in 10.5.5
+main.grant : Modified in 10.5.7
+main.grant5 : Modified in 10.5.7
+main.grant_kill : MDEV-23915 - Wrong result
main.having : MDEV-23420 - Server crash
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 - Plan mismatch; modified in 10.5.4
-main.information_schema : Modified in 10.5.5
-main.information_schema_all_engines : MDEV-23421 - Wrong result; configuration modified in 10.5.5
-main.information_schema_db : Modified in 10.5.4
-main.innodb_ext_key : Modified in 10.5.4
+main.implicit_commit : Modified in 10.5.7
+main.index_intersect : MDEV-23921 - Wrong result
+main.index_intersect_innodb : MDEV-23921 - Wrong result; MDEV-10643 - failed with timeout
+main.index_merge_innodb : MDEV-7142 - Plan mismatch
+main.information_schema : Modified in 10.5.7
+main.information_schema_all_engines : MDEV-23421 - Wrong result
+main.innodb_ext_key : Modified in 10.5.7
main.innodb_icp : MDEV-20168 - Wrong execution plans
-main.innodb_mrr_cpk : MDEV-23370 - Server crash
+main.innodb_icp_debug : Added in 10.5.7
+main.invisible_field : Modified in 10.5.7
main.invisible_field_grant_completely : MDEV-22254 - Syscall param write points to uninitialised bytes
main.ipv4_and_ipv6 : MDEV-20964 - Wrong result
main.ipv6 : MDEV-20964 - Wrong result
main.join_cache : MDEV-17743 - Bad address from storage engine MyISAM
-main.join_outer : Modified in 10.5.5
-main.kill : Modified in 10.5.4
-main.kill-2 : MDEV-13257 - Wrong result; modified in 10.5.4
+main.kill : Modified in 10.5.7
+main.kill-2 : MDEV-13257 - Wrong result
main.kill_processlist-6619 : MDEV-10793 - Wrong result
+main.limit_rows_examined : Modified in 10.5.7
main.loaddata : MDEV-19368 - mysqltest failed but provided no output
main.locale : MDEV-20521 - Missing warning
-main.lock : Modified in 10.5.4
+main.lock_view : Added in 10.5.7
main.log_slow : MDEV-13263 - Wrong result
-main.log_tables : Modified in 10.5.5
+main.log_tables : Modified in 10.5.7
main.log_tables-big : MDEV-13408 - wrong result
main.log_tables_upgrade : MDEV-20962 - Wrong result
-main.long_unique_bugs : Modified in 10.5.4
-main.long_unique_bugs_replication : Added in 10.5.4
-main.lowercase_fs_off : Modified in 10.5.5
-main.mdev-21101 : Added in 10.5.5
main.mdev-504 : MDEV-15171 - warning
main.mdev375 : MDEV-10607 - sporadic "can't connect"
-main.mdev_22370 : Added in 10.5.4
-main.mdl : MDEV-22954 - Wrong result; modified in 10.5.5
+main.mdl : MDEV-22954 - Wrong result
main.merge : MDEV-10607 - sporadic "can't connect"
-main.myisampack : Modified in 10.5.4
+main.multi_update_big : Modified in 10.5.7
+main.myisam_icp_debug : Added in 10.5.7
+main.myisam_icp_notembedded : MDEV-23420 - Server crash
main.mysql : MDEV-20156 - Wrong result
main.mysql_client_test : MDEV-19369 - error: 5888, status: 23, errno: 2; MDEV-19511 - Big endian issue
main.mysql_client_test_comp : MDEV-16641 - Error in exec
main.mysql_client_test_nonblock : CONC-208 - Error on Power; MDEV-15096 - exec failed
main.mysql_cp932 : MDEV-21275 - Wrong result
-main.mysql_install_db_win : Modified in 10.5.5
-main.mysql_upgrade : MDEV-20161 - Wrong result; MDEV-20166 - FATAL ERROR: Upgrade failed; modified in 10.5.5
+main.mysql_json_table_recreate : Added in 10.5.7
+main.mysql_upgrade : MDEV-20161 - Wrong result; MDEV-20166 - FATAL ERROR: Upgrade failed; modified in 10.5.7
main.mysql_upgrade-6984 : MDEV-22514 - Wrong result
+main.mysql_upgrade_mysql_json_datatype : Added in 10.5.7
main.mysql_upgrade_no_innodb : MDEV-20537 - Wrong result
main.mysql_upgrade_noengine : MDEV-14355 - Wrong result
main.mysql_upgrade_view : MDEV-23392 - Wrong result; MDEV-20161 - Wrong result
main.mysqladmin : MDEV-20535 - Wrong result
main.mysqlbinlog_row_compressed : MDEV-22964 - Wrong result
+main.mysqlbinlog_row_minimal : Modified in 10.5.7
main.mysqlcheck : MDEV-20164 - Wrong result
-main.mysqld--help-aria : Modified in 10.5.5
+main.mysqld--help : Modified in 10.5.7
main.mysqld_option_err : MDEV-21236 - Wrong error; MDEV-21571 - Crash on bootstrap
-main.mysqldump : MDEV-14800 - Stack smashing detected
+main.mysqldump : MDEV-14800 - Stack smashing detected; modified in 10.5.7
main.mysqldump-max : MDEV-21272 - Wrong result
main.mysqlhotcopy_myisam : MDEV-10995 - Hang on debug
-main.mysqlshow : MDEV-20965 - Wrong result; modified in 10.5.4
+main.mysqlshow : MDEV-20965 - Wrong result
main.mysqlslap : MDEV-11801 - timeout
main.mysqltest : MDEV-13887 - Wrong result
-main.mysqltest_tracking_info : Modified in 10.5.5
-main.named_pipe : MDEV-23279 - Test timeouts; modified in 10.5.4
-main.nested_profiling : Added in 10.5.5
+main.named_pipe : Modified in 10.5.7
main.old-mode : MDEV-19373 - Wrong result
main.openssl_6975 : MDEV-17184 - Failures with OpenSSL 1.1.1
-main.opt_trace : Modified in 10.5.5
-main.order_by : Modified in 10.5.5
+main.opt_trace : Modified in 10.5.7
+main.order_by : Modified in 10.5.7
main.order_by_optimizer_innodb : MDEV-10683 - Wrong result
-main.parser : Modified in 10.5.5
-main.partition : Modified in 10.5.5
-main.partition_alter : Modified in 10.5.4
+main.parser : Modified in 10.5.7
+main.partition : Modified in 10.5.7
main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock
-main.partition_explicit_prune : Modified in 10.5.5
-main.partition_innodb : MDEV-20169 - Wrong result
+main.partition_innodb : MDEV-20169 - Wrong result; MDEV-23427 - Server crash
main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings
main.partition_innodb_semi_consistent : MDEV-19411 - Failed to start mysqld.1
-main.percona_nonflushing_analyze_debug : Added in 10.5.4
-main.plugin : Modified in 10.5.5
main.plugin_auth : MDEV-20957 - Upgrade file was not properly created
main.plugin_auth_qa_2 : MDEV-20165 - Wrong result
-main.pool_of_threads : MDEV-18135 - SSL error: key too small
-main.processlist_notembedded : Modified in 10.5.4
-main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.5.4
-main.query_cache : MDEV-16180 - Wrong result; modified in 10.5.4
+main.plugin_innodb : Modified in 10.5.7
+main.pool_of_threads : MDEV-18135 - SSL error: key too small; modified in 10.5.7
+main.precedence : Added in 10.5.7
+main.precedence_bugs : Added in 10.5.7
+main.processlist_notembedded : Modified in 10.5.7
+main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count
+main.ps_error : MDEV-24079 - Memory not freed
+main.query_cache : MDEV-16180 - Wrong result
main.query_cache_debug : MDEV-15281 - Query cache is disabled
+main.range : Modified in 10.5.7
main.range_innodb : MDEV-23371 - Server crash
main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away
-main.repair : Modified in 10.5.4
-main.row : Modified in 10.5.4
+main.repair_symlink-5543 : MDEV-23920 - Wrong result
+main.rowid_filter : Modified in 10.5.7
main.rowid_filter_innodb : MDEV-20538 - Wrong result
-main.rowid_filter_myisam : Added in 10.5.5
+main.rowid_filter_innodb_debug : Added in 10.5.7
+main.rowid_filter_myisam_debug : Added in 10.5.7
main.select : MDEV-20532 - Floating point differences
main.select_jcl6 : MDEV-20532 - Floating point differences
main.select_pkeycache : MDEV-20532 - Floating point differences
-main.selectivity : Modified in 10.5.4
main.set_statement : MDEV-13183 - Wrong result
-main.set_statement_notembedded : MDEV-19414 - Wrong result
+main.set_statement_notembedded : MDEV-19414 - Wrong result; modified in 10.5.7
main.shm : MDEV-12727 - Mismatch, ERROR 2013
main.show_explain : MDEV-10674 - Wrong result code
-main.signal : Modified in 10.5.5
-main.sp : MDEV-7866 - Mismatch; modified in 10.5.5
-main.sp-error : Modified in 10.5.5
-main.sp-security : MDEV-10607 - sporadic "can't connect"; modified in 10.5.4
-main.sp-vars : Modified in 10.5.4
-main.sp2 : Added in 10.5.4
+main.sp : MDEV-7866 - Mismatch; modified in 10.5.7
+main.sp-destruct : Modified in 10.5.7
+main.sp-security : MDEV-10607 - sporadic "can't connect"
main.sp_notembedded : MDEV-10607 - internal error
main.ssl : MDEV-17184 - Failures with OpenSSL 1.1.1
main.ssl_7937 : MDEV-20958 - Wrong result
main.ssl_ca : MDEV-10895 - SSL connection error on Power
main.ssl_cipher : MDEV-17184 - Failures with OpenSSL 1.1.1
main.ssl_timeout : MDEV-11244 - Crash
-main.stat_tables_innodb : Modified in 10.5.5
main.stat_tables_par_innodb : MDEV-14155 - Wrong rounding
-main.stat_tables_partition : Modified in 10.5.5
main.status : MDEV-13255 - Wrong result
-main.status_bug17954 : Modified in 10.5.4
main.subselect : MDEV-20551 - Valgrind failure
-main.subselect4 : Modified in 10.5.5
-main.subselect_exists2in : Modified in 10.5.5
-main.subselect_innodb : MDEV-10614 - Wrong result
-main.table_value_constr : Modified in 10.5.4
+main.subselect4 : Modified in 10.5.7
+main.subselect_innodb : MDEV-10614 - Wrong result; modified in 10.5.7
+main.sum_distinct-big : Modified in 10.5.7
main.tc_heuristic_recover : MDEV-14189 - Wrong result
-main.temp_table : Modified in 10.5.5
+main.temp_table_symlink : MDEV-24058 - Wrong error code; added in 10.5.7
main.tls_version : MDEV-23417 - Wrong result
-main.type_bit : Modified in 10.5.5
-main.type_blob : MDEV-15195 - Wrong result
-main.type_date : Modified in 10.5.5
-main.type_datetime : Modified in 10.5.4
-main.type_datetime_hires : MDEV-10687 - Timeout; modified in 10.5.5
-main.type_enum : Modified in 10.5.5
-main.type_float : MDEV-20532 - Floating point differences; modified in 10.5.5
-main.type_hex_hybrid : Modified in 10.5.5
-main.type_int : Modified in 10.5.5
-main.type_newdecimal : MDEV-20532 - Floating point differences
+main.type_blob : MDEV-15195 - Wrong result; modified in 10.5.7
+main.type_date : Modified in 10.5.7
+main.type_datetime : Modified in 10.5.7
+main.type_datetime_hires : MDEV-10687 - Timeout
+main.type_float : MDEV-20532 - Floating point differences; modified in 10.5.7
+main.type_newdecimal : MDEV-20532 - Floating point differences; modified in 10.5.7
main.type_ranges : MDEV-20532 - Floating point differences
-main.type_set : Modified in 10.5.5
-main.type_temporal_innodb : Modified in 10.5.5
-main.type_time : Modified in 10.5.4
-main.type_time_hires : Modified in 10.5.5
-main.type_timestamp : Modified in 10.5.4
-main.type_timestamp_hires : Modified in 10.5.5
-main.type_year : Modified in 10.5.5
-main.udf : Modified in 10.5.4
-main.union : Modified in 10.5.5
-main.upgrade_MDEV-19650 : Modified in 10.5.5
-main.upgrade_MDEV-23102-1 : Added in 10.5.5
-main.upgrade_MDEV-23102-2 : Added in 10.5.5
+main.type_temporal_innodb : MDEV-24025 - Wrong result
+main.type_time : Modified in 10.5.7
+main.udf : Modified in 10.5.7
main.userstat : MDEV-12904 - SSL errors
-main.view : Modified in 10.5.4
+main.view : Modified in 10.5.7
main.wait_timeout : MDEV-19023 - Lost connection to MySQL server during query
-main.warnings_debug : Modified in 10.5.4
-main.win : Modified in 10.5.5
-main.win_ntile : Modified in 10.5.5
-main.win_percentile : Modified in 10.5.4
-main.xa : MDEV-11769 - lock wait timeout; modified in 10.5.4
-main.xa_binlog : Modified in 10.5.4
+main.win : Modified in 10.5.7
+main.windows_debug : Added in 10.5.7
+main.xa : MDEV-11769 - lock wait timeout
main.xml : MDEV-21968 - Crash on armhf
#-----------------------------------------------------------------------
@@ -270,34 +232,30 @@ archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed
#-----------------------------------------------------------------------
-binlog.binlog_base64_flag : Modified in 10.5.4
-binlog.binlog_commit_wait : MDEV-10150 - Mismatch
-binlog.binlog_drop_if_exists : Modified in 10.5.4
-binlog.binlog_empty_xa_prepared : Added in 10.5.5
-binlog.binlog_innodb : MDEV-22516 - Wrong result
-binlog.binlog_invalid_read_in_rotate : MDEV-22455 - Server crash
-binlog.binlog_ioerr : MDEV-20159 - Assertion failure
-binlog.binlog_killed : MDEV-12925 - Wrong result
-binlog.binlog_max_extension : MDEV-19762 - Crash on shutdown
-binlog.binlog_mixed : Added in 10.5.4
-binlog.binlog_mysqlbinlog_row_frag : Modified in 10.5.4
-binlog.binlog_mysqlbinlog_row_innodb : MDEV-20530 - Binary files differ
-binlog.binlog_mysqlbinlog_row_myisam : MDEV-20530 - Binary files differ
-binlog.binlog_no_uniqfile_crash : Added in 10.5.4
-binlog.binlog_parallel_replication_marks_row : Include file modified in 10.5.5
-binlog.binlog_parallel_replication_marks_stm_mix : Include file modified in 10.5.5
-binlog.binlog_row_binlog : MDEV-23402 - Wrong result; include file modified in 10.5.4
-binlog.binlog_show_binlog_event_random_pos : MDEV-22473 - Server crash
-binlog.binlog_stm_binlog : MDEV-20412 - Wrong result; include file modified in 10.5.4
-binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
-binlog.flashback-largebinlog : MDEV-19764 - Out of memory
-binlog.load_data_stm_view : MDEV-16948 - Wrong result
-binlog.show_concurrent_rotate : MDEV-20215 - Wrong result
+binlog.binlog_commit_wait : MDEV-10150 - Mismatch
+binlog.binlog_innodb : MDEV-22516 - Wrong result
+binlog.binlog_ioerr : MDEV-20159 - Assertion failure
+binlog.binlog_killed : MDEV-12925 - Wrong result
+binlog.binlog_max_extension : MDEV-19762 - Crash on shutdown
+binlog.binlog_mysqlbinlog_row : Modified in 10.5.7
+binlog.binlog_mysqlbinlog_row_frag : Modified in 10.5.7
+binlog.binlog_mysqlbinlog_row_innodb : MDEV-20530 - Binary files differ
+binlog.binlog_mysqlbinlog_row_myisam : MDEV-20530 - Binary files differ
+binlog.binlog_no_uniqfile_crash : MDEV-24078 - Server crash upon shutdown
+binlog.binlog_recover_checksum_error : Added in 10.5.7
+binlog.binlog_row_binlog : MDEV-23402 - Wrong result
+binlog.binlog_show_binlog_event_random_pos : Modified in 10.5.7
+binlog.binlog_stm_binlog : MDEV-20412 - Wrong result
+binlog.binlog_stm_mix_innodb_myisam : MDEV-24057 - Wrong result
+binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
+binlog.flashback-largebinlog : MDEV-19764 - Out of memory
+binlog.load_data_stm_view : MDEV-16948 - Wrong result
+binlog.show_concurrent_rotate : MDEV-20215 - Wrong result
#-----------------------------------------------------------------------
binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint
-binlog_encryption.encrypted_master : MDEV-14201 - Extra warnings
+binlog_encryption.encrypted_master : MDEV-23905 - Failure upon post-check; MDEV-23637 - Assertion failure; MDEV-14201 - Extra warnings
binlog_encryption.encrypted_master_switch_to_unencrypted : MDEV-14190 - Can't init tc log
binlog_encryption.encrypted_slave : MDEV-18135 - SSL error: key too small
binlog_encryption.encryption_combo : MDEV-14199 - Table is marked as crashed
@@ -311,6 +269,7 @@ binlog_encryption.rpl_loadfile : MDEV-16645 - Timeou
binlog_encryption.rpl_mixed_binlog_max_cache_size : MDEV-20956 - Incorrect checksum for freed object
binlog_encryption.rpl_parallel : MDEV-10653 - Timeout in include
binlog_encryption.rpl_parallel_ignored_errors : MDEV-22471 - Slave crash
+binlog_encryption.rpl_parallel_stop_on_con_kill : MDEV-24086 - Timeout
binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout
binlog_encryption.rpl_semi_sync : MDEV-11673 - Valgrind
binlog_encryption.rpl_skip_replication : MDEV-13571 - Unexpected warning; MDEV-20573 - Wrong result
@@ -322,21 +281,8 @@ binlog_encryption.rpl_typeconv : MDEV-14362 - Lost c
#-----------------------------------------------------------------------
-columnstore.* : Engine enabled in 10.5.4
-
-#-----------------------------------------------------------------------
-
-compat/maxdb.rpl_mariadb_timestamp : Added in 10.5.5
-compat/maxdb.type_timestamp : Added in 10.5.5
-
-#-----------------------------------------------------------------------
-
-compat/oracle.binlog_ptr_mysqlbinlog : Added in 10.5.5
-compat/oracle.parser : Modified in 10.5.4
-compat/oracle.rpl_mariadb_date : Added in 10.5.5
-compat/oracle.sp : Modified in 10.5.5
-compat/oracle.sp-cursor-rowtype : Modified in 10.5.5
-compat/oracle.type_date : Modified in 10.5.5
+compat/oracle.parser : Modified in 10.5.7
+compat/oracle.sp-package : Modified in 10.5.7
#-----------------------------------------------------------------------
@@ -347,7 +293,7 @@ connect.part_file : MDEV-18135 - SSL error: key too small
connect.part_table : MDEV-18135 - SSL error: key too small
connect.pivot : MDEV-14803 - Failed to discover table
connect.secure_file_priv : MDEV-18135 - SSL error: key too small
-connect.type_inet6 : Added in 10.5.4
+connect.updelx : Modified in 10.5.7
connect.vcol : MDEV-12374 - Fails on Windows
connect.zip : MDEV-13884 - Wrong result
@@ -357,8 +303,9 @@ disks.disks_notembedded : MDEV-21587 - Wrong result
#-----------------------------------------------------------------------
-encryption.corrupted_during_recovery : MDEV-20159 - Assertion failure; modified in 10.5.4
-encryption.create_or_replace : MDEV-16115 - Trying to access tablespace
+encryption.corrupted_during_recovery : MDEV-20159 - Assertion failure
+encryption.create_or_replace : MDEV-24081 - Lock wait timeout exceeded; modified in 10.5.7
+encryption.create_or_replace_big : Added in 10.5.7
encryption.debug_key_management : MDEV-13841 - Timeout
encryption.encrypt_and_grep : MDEV-13765 - Wrong result
encryption.innochecksum : MDEV-13644 - Assertion failure
@@ -370,26 +317,27 @@ encryption.innodb-first-page-read : MDEV-14356 - Timeout in wait
encryption.innodb-force-corrupt : MDEV-17286 - SSL error
encryption.innodb-missing-key : MDEV-14728 - SSL error
encryption.innodb-page_encryption : MDEV-10641 - mutex problem
-encryption.innodb-page_encryption_log_encryption : MDEV-17339 - Crash on restart
+encryption.innodb-page_encryption_compression : Modified in 10.5.7
+encryption.innodb-page_encryption_log_encryption : MDEV-17339 - Crash on restart; modified in 10.5.7
encryption.innodb-read-only : MDEV-16563 - Crash on startup
-encryption.innodb-redo-badkey : Modified in 10.5.4
+encryption.innodb-redo-badkey : MDEV-12898 - Server hang on startup
encryption.innodb-redo-nokeys : MDEV-20159 - Assertion failure
-encryption.innodb-remove-encryption : MDEV-16493 - Timeout in wait condition
+encryption.innodb-remove-encryption : MDEV-16493 - Timeout in wait condition; modified in 10.5.7
encryption.innodb-spatial-index : MDEV-13746 - Wrong result
-encryption.innodb_encrypt_key_rotation_age : MDEV-19763 - Timeout
+encryption.innodb_encrypt_key_rotation_age : MDEV-19763 - Timeout; modified in 10.5.7
encryption.innodb_encrypt_log : MDEV-13725 - Wrong result
encryption.innodb_encrypt_log_corruption : MDEV-14379 - Server crash
-encryption.innodb_encrypt_temporary_tables : MDEV-20142 - Wrong result; modified in 10.5.5
+encryption.innodb_encrypt_temporary_tables : MDEV-20142 - Wrong result
encryption.innodb_encryption : MDEV-14728 - Unable to get certificate; MDEV-15675 - Timeout
encryption.innodb_encryption-page-compression : MDEV-12630 - Crash or assertion failure; MDEV-21843 - Assertion failure
-encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result
+encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result; configuration modified in 10.5.7
encryption.innodb_encryption_filekeys : MDEV-15673 - Timeout
encryption.innodb_encryption_is : MDEV-12898 - Server hang on startup
encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash
encryption.innodb_encryption_tables : MDEV-17339 - Crash on restart
encryption.innodb_first_page : MDEV-10689 - Crash
encryption.innodb_onlinealter_encryption : MDEV-17287 - SIGABRT on server restart
-encryption.tempfiles_encrypted : Added in 10.5.4
+encryption.tempfiles_encrypted : Modified in 10.5.7
#-----------------------------------------------------------------------
@@ -412,8 +360,7 @@ federated.federated_innodb : MDEV-10617 - Wrong checksum
federated.federated_partition : MDEV-10417 - Fails on Mips
federated.federated_transactions : MDEV-10617 - Wrong checksum
federated.federatedx : MDEV-10617 - Wrong checksum
-federated.federatedx_create_handlers : Modified in 10.5.5
-federated.federatedx_versioning : Modified in 10.5.4
+federated.federatedx_create_handlers : Modified in 10.5.7
#-----------------------------------------------------------------------
@@ -440,57 +387,53 @@ galera_3nodes.* : Suite is not stable yet
#-----------------------------------------------------------------------
-gcol.gcol_bugfixes : Modified in 10.5.5
-gcol.gcol_purge : Added in 10.5.4
+gcol.gcol_keys_innodb : Include file modified in 10.5.7
+gcol.gcol_keys_myisam : Include file modified in 10.5.7
+gcol.gcol_partition_innodb : Include file modified in 10.5.7
+gcol.gcol_purge : Include file modified in 10.5.7
+gcol.gcol_update : Include file modified in 10.5.7
gcol.innodb_virtual_basic : MDEV-16950 - Failing assertion
gcol.innodb_virtual_debug : MDEV-23404 - Server crash; MDEV-23112 - Server crash
-gcol.innodb_virtual_debug_purge : MDEV-16952 - Wrong result
+gcol.innodb_virtual_debug_purge : Include file modified in 10.5.7
+gcol.innodb_virtual_fk : MDEV-20640 - Assertion failure; modified in 10.5.7
gcol.innodb_virtual_fk_restart : MDEV-17466 - Assertion failure
-gcol.innodb_virtual_purge : MDEV-22952 - Lock wait timeout
+gcol.innodb_virtual_index : Modified in 10.5.7
+gcol.innodb_virtual_purge : MDEV-22952 - Lock wait timeout; include file modified in 10.5.7
gcol.main_alter_table : MDEV-23403 - Wrong result
#-----------------------------------------------------------------------
-handler.aria : Include file modified in 10.5.4
-handler.heap : Include file modified in 10.5.4
-handler.innodb : Modified in 10.5.4
-handler.myisam : Include file modified in 10.5.4
-
-#-----------------------------------------------------------------------
-
-heap.drop : Added in 10.5.5
-
-#-----------------------------------------------------------------------
-
innodb.101_compatibility : MDEV-13891 - Wrong result
innodb.alter_copy : MDEV-16181 - Assertion failure
-innodb.alter_crash : MDEV-16944 - The process cannot access the file; modified in 10.5.4
+innodb.alter_crash : MDEV-16944 - The process cannot access the file
innodb.alter_large_dml : MDEV-20148 - Debug sync point wait timed out
-innodb.alter_primary_key : Added in 10.5.5
-innodb.analyze_table : Modified in 10.5.4
+innodb.alter_table : Modified in 10.5.7
innodb.binlog_consistent : MDEV-10618 - Server fails to start
innodb.blob-crash : MDEV-20481 - Crash during recovery
-innodb.corrupted_during_recovery : Modified in 10.5.4
innodb.create-index : MDEV-20159 - Assertion failure
-innodb.default_row_format_alter : Modified in 10.5.5
innodb.default_row_format_compatibility : MDEV-20159 - Assertion failure
innodb.doublewrite : MDEV-12905 - Server crash
-innodb.foreign_key : MDEV-21283 - Extra warning; modified in 10.5.4
+innodb.flush : Added in 10.5.7
+innodb.foreign-keys : Modified in 10.5.7
+innodb.foreign_key : MDEV-21283 - Extra warning; modified in 10.5.7
innodb.group_commit_crash : MDEV-14191 - InnoDB registration failed
innodb.group_commit_crash_no_optimize_thread : MDEV-11770 - Checksum mismatch
-innodb.ibuf_not_empty : MDEV-19021 - Wrong result
-innodb.innodb : Modified in 10.5.5
+innodb.ibuf_not_empty : MDEV-19021 - Wrong result; modified in 10.5.7
+innodb.innodb : Modified in 10.5.7
innodb.innodb-32k-crash : MDEV-20194 - Extra warnings
+innodb.innodb-64k : Modified in 10.5.7
innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup
-innodb.innodb-alter : MDEV-22955 - Extra warning; modified in 10.5.5
-innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.5.4
+innodb.innodb-alter : MDEV-22955 - Extra warning
+innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS
innodb.innodb-alter-table : MDEV-10619 - Testcase timeout
innodb.innodb-bigblob : MDEV-18655 - ASAN unknown crash
innodb.innodb-blob : MDEV-12053 - Client crash
-innodb.innodb-change-buffer-recovery : MDEV-19115 - Lost connection to MySQL server during query
+innodb.innodb-change-buffer-recovery : MDEV-19115 - Lost connection to MySQL server during query; modified in 10.5.7
innodb.innodb-dict : MDEV-20159 - Assertion failure
-innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown; modified in 10.5.4
+innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown
innodb.innodb-get-fk : MDEV-13276 - Server crash
+innodb.innodb-index : Include file modified in 10.5.7
+innodb.innodb-index-debug : Include file modified in 10.5.7
innodb.innodb-index-online : MDEV-14809 - Cannot save statistics
innodb.innodb-page_compression_default : MDEV-13644 - Assertion failure
innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result
@@ -499,73 +442,73 @@ innodb.innodb-page_compression_tables : MDEV-13644 - Assertion failure
innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem
innodb.innodb-table-online : MDEV-13894 - Wrong result
innodb.innodb-timeout : MDEV-20159 - Assertion failure
-innodb.innodb-ucs2 : MDEV-23370 - Server crash
+innodb.innodb-trim : Modified in 10.5.7
innodb.innodb-wl5522 : MDEV-13644 - Assertion failure
innodb.innodb-wl5522-1 : MDEV-22945 - Server crash
-innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno
+innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno; modified in 10.5.7
innodb.innodb_buffer_pool_dump_pct : MDEV-20139 - Timeout in wait_condition.inc
innodb.innodb_buffer_pool_resize : MDEV-16964 - Assertion failure
-innodb.innodb_buffer_pool_resize_debug : MDEV-22515 - Timeout in wait_condition; modified in 10.5.5
+innodb.innodb_buffer_pool_resize_debug : MDEV-22515 - Timeout in wait_condition
innodb.innodb_buffer_pool_resize_with_chunks : MDEV-16964 - Assertion failure
-innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt; modified in 10.5.4
+innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt
innodb.innodb_bug30423 : MDEV-7311 - Wrong result
innodb.innodb_bug47167 : MDEV-20524 - Table 'user' is marked as crashed and should be repaired
innodb.innodb_bug48024 : MDEV-14352 - Assertion failure
innodb.innodb_bulk_create_index_replication : MDEV-15273 - Slave failed to start
-innodb.innodb_ctype_ldml : Modified in 10.5.5
innodb.innodb_defrag_stats_many_tables : MDEV-14198 - Table is full
-innodb.innodb_force_recovery : Modified in 10.5.4
-innodb.innodb_force_recovery_rollback : MDEV-22889 - Wrong result; modified in 10.5.5
+innodb.innodb_force_recovery_rollback : MDEV-22889 - Wrong result
innodb.innodb_information_schema : MDEV-8851 - Wrong result
-innodb.innodb_information_schema_buffer : MDEV-23418 - Wrong result; modified in 10.5.4
+innodb.innodb_information_schema_buffer : MDEV-23418 - Wrong result
innodb.innodb_max_recordsize_32k : MDEV-14801 - Operation failed
innodb.innodb_max_recordsize_64k : MDEV-15203 - Wrong result
innodb.innodb_monitor : MDEV-10939 - Testcase timeout
innodb.innodb_mutexes : MDEV-23416 - Extra warning
-innodb.innodb_mysql : MDEV-19873 - Wrong result; include file modified in 10.5.5
-innodb.innodb_scrub : Added in 10.5.4
+innodb.innodb_mysql : MDEV-19873 - Wrong result
+innodb.innodb_scrub : Modified in 10.5.7
innodb.innodb_simulate_comp_failures_small : MDEV-20526 - ASAN use-after-poison
-innodb.innodb_skip_innodb_is_tables : Configuration modified in 10.5.5
innodb.innodb_stats : MDEV-10682 - wrong result
-innodb.innodb_stats_persistent : MDEV-17745 - Wrong result; MDEV-21567 - Wrong result in execution plan
+innodb.innodb_stats_drop_locked : Modified in 10.5.7
+innodb.innodb_stats_persistent : MDEV-21567 - Wrong result in execution plan
innodb.innodb_stats_persistent_debug : MDEV-14801 - Operation failed
innodb.innodb_sys_semaphore_waits : MDEV-10331 - Semaphore wait
+innodb.innodb_trx_weight : Configuration deleted in 10.5.7
innodb.innodb_zip_innochecksum2 : MDEV-13882 - Warning: difficult to find free blocks
-innodb.instant_alter_bugs : Modified in 10.5.5
-innodb.instant_alter_charset : Modified in 10.5.5
-innodb.instant_alter_debug : MDEV-22958 - Wrong result; modified in 10.5.5
-innodb.instant_alter_extend : MDEV-20963 - Binary files differ; modified in 10.5.5
-innodb.instant_alter_limit : Modified in 10.5.4
-innodb.leaf_page_corrupted_during_recovery : Modified in 10.5.4
+innodb.instant_alter_bugs : Modified in 10.5.7
+innodb.instant_alter_crash : Modified in 10.5.7
+innodb.instant_alter_extend : MDEV-20963 - Binary files differ
+innodb.instant_alter_index_rename : Modified in 10.5.7
innodb.log_corruption : MDEV-13251 - Wrong result
innodb.log_data_file_size : MDEV-14204 - Server failed to start; MDEV-20648 - Assertion failure
innodb.log_file : MDEV-20159 - Assertion failure
innodb.log_file_name : MDEV-14193 - Exception
innodb.log_file_size : MDEV-15668 - Not found pattern
+innodb.max_record_size : MDEV-23420 - Server crash
innodb.monitor : MDEV-16179 - Wrong result
-innodb.mvcc : Modified in 10.5.5
innodb.page_id_innochecksum : MDEV-20159 - Assertion failure
-innodb.purge_secondary : MDEV-15681 - Wrong result
+innodb.purge_secondary : MDEV-15681 - Wrong result; modified in 10.5.7
innodb.purge_thread_shutdown : MDEV-13792 - Wrong result
-innodb.read_only_recover_committed : Modified in 10.5.5
innodb.read_only_recovery : MDEV-13886 - Server crash
innodb.recovery_shutdown : MDEV-15671 - Checksum mismatch in datafile
-innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace
-innodb.table_definition_cache_debug : MDEV-14206 - Extra warning
-innodb.table_flags : MDEV-13572 - Wrong result; MDEV-19374 - Server failed to start
-innodb.temp_table_savepoint : Modified in 10.5.4
-innodb.temporary_table : MDEV-13265 - Wrong result
-innodb.truncate_foreign : Modified in 10.5.5
-innodb.undo_truncate : MDEV-17340 - Server hung; MDEV-20840 - Sporadic timeout
+innodb.redo_log_during_checkpoint : Modified in 10.5.7
+innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace; modified in 10.5.7
+innodb.stats_persistent : Added in 10.5.7
+innodb.table_definition_cache_debug : MDEV-14206 - Extra warning; modified in 10.5.7
+innodb.table_flags : MDEV-13572 - Wrong result; MDEV-19374 - Server failed to start; modified in 10.5.7
+innodb.temp_table_savepoint : MDEV-24077 - Assertion failure
+innodb.temporary_table : MDEV-13265 - Wrong result; modified in 10.5.7
+innodb.truncate : Modified in 10.5.7
+innodb.undo_truncate : MDEV-17340 - Server hung; MDEV-20840 - Sporadic timeout; modified in 10.5.7
innodb.undo_truncate_recover : MDEV-17679 - Server has gone away; MDEV-19200 - Shutdown fails
+innodb.update-cascade : Combinations added in 10.5.7
innodb.update_time : MDEV-14804 - Wrong result
-innodb.xa_recovery : MDEV-15279 - mysqld got exception; modified in 10.5.4
-innodb.xa_recovery_debug : Modified in 10.5.4
+innodb.xa_recovery : MDEV-15279 - mysqld got exception
#-----------------------------------------------------------------------
-innodb_fts.innodb-fts-ddl : Modified in 10.5.5
+innodb_fts.basic : Modified in 10.5.7
+innodb_fts.fulltext2 : MDEV-24074 - Server crash
innodb_fts.innodb_fts_misc : MDEV-22955 - Extra warning
+innodb_fts.innodb_fts_misc_1 : Modified in 10.5.7
innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning
innodb_fts.innodb_fts_plugin : MDEV-13888 - Errors in server log
innodb_fts.innodb_fts_stopword_charset : MDEV-13259 - Table crashed
@@ -575,23 +518,25 @@ innodb_fts.sync_ddl : MDEV-21568 - Errno: 2000; MDEV-18654 -
innodb_gis.alter_spatial_index : MDEV-13745 - Server crash
innodb_gis.gis_split_nan : MDEV-21678 - Cannot get geometry object
+innodb_gis.rtree_add_index : Include file modified in 10.5.7
+innodb_gis.rtree_compress : Include file modified in 10.5.7
innodb_gis.rtree_compress2 : MDEV-16269 - Wrong result
innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded
-innodb_gis.rtree_purge : MDEV-15275 - Timeout
+innodb_gis.rtree_purge : MDEV-15275 - Timeout; include file modified in 10.5.7
innodb_gis.rtree_recovery : MDEV-15274 - Error on check
innodb_gis.rtree_split : MDEV-14208 - Too many arguments
-innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file
+innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file; include file modified in 10.5.7
innodb_gis.types : MDEV-15679 - Table is marked as crashed
#-----------------------------------------------------------------------
+innodb_zip.blob : Include file modified in 10.5.7
innodb_zip.cmp_per_index : MDEV-14490 - Table is marked as crashed
-innodb_zip.create_options : MDEV-21329 - Assertion failure
+innodb_zip.create_options : MDEV-21329 - Assertion failure; MDEV-24076 - Assertion failure
innodb_zip.index_large_prefix_4k : MDEV-21679 - Row size too large
innodb_zip.innochecksum : MDEV-14486 - Server failed to shut down
innodb_zip.innochecksum_3 : MDEV-13279 - Extra warnings
-innodb_zip.recover : MDEV-22512 - Server failed to restart
-innodb_zip.restart : MDEV-23422 - Wrong result
+innodb_zip.restart : Modified in 10.5.7
innodb_zip.wl5522_debug_zip : MDEV-11600 - Operating system error number 2
innodb_zip.wl6470_1 : MDEV-14240 - Assertion failure
innodb_zip.wl6501_1 : MDEV-10891 - Can't create UNIX socket
@@ -599,39 +544,37 @@ innodb_zip.wl6501_scale_1 : MDEV-13254 - Timeout, MDEV-14104 - Error 192
#-----------------------------------------------------------------------
-maria.bulk_insert_crash : Added in 10.5.4
-maria.create : Modified in 10.5.4
-maria.encrypt-no-key : Added in 10.5.5
+maria.alter : Modified in 10.5.7
+maria.create : Modified in 10.5.7
maria.insert_select : MDEV-12757 - Timeout
maria.insert_select-7314 : MDEV-16492 - Timeout
-maria.lock : Modified in 10.5.4
maria.maria : MDEV-14430 - Extra warning
-maria.maria-connect : Modified in 10.5.4
-maria.maria-no-logging : MDEV-20196 - Crash on shutdown or server can't start
-maria.rollback : Added in 10.5.4
-maria.transaction : Added in 10.5.4
+maria.maria-no-logging : MDEV-20196 - Crash on shutdown or server can't start; modified in 10.5.7
#-----------------------------------------------------------------------
mariabackup.absolute_ibdata_paths : MDEV-16571 - Wrong result
mariabackup.apply-log-only : MDEV-20135 - Timeout
+mariabackup.backup_ssl : MDEV-24073 - Server crash upon shutdown
mariabackup.create_with_data_directory_during_backup : MDEV-20159 - Assertion failure
mariabackup.data_directory : MDEV-15270 - Error on exec
mariabackup.full_backup : MDEV-16571 - Wrong result
-mariabackup.huge_lsn : MDEV-18569 - Table doesn't exist; modified in 10.5.5
+mariabackup.huge_lsn : MDEV-18569 - Table doesn't exist
mariabackup.incremental_backup : MDEV-21222 - Memory allocation failure
+mariabackup.incremental_ddl_during_backup : Modified in 10.5.7
mariabackup.incremental_encrypted : MDEV-15667 - timeout
mariabackup.incremental_rocksdb : MDEV-20954 - Cannot access the file
+mariabackup.innodb_redo_overwrite : MDEV-24023 - Wrong result; added in 10.5.7
mariabackup.log_checksum_mismatch : MDEV-16571 - Wrong result
mariabackup.mdev-14447 : MDEV-15201 - Timeout
-mariabackup.options_check : Modified in 10.5.5
mariabackup.partial_exclude : MDEV-15270 - Error on exec
-mariabackup.unencrypted_page_compressed : MDEV-18653 - Wrong error
+mariabackup.rpl_slave_info : Added in 10.5.7
+mariabackup.undo_space_id : MDEV-24022 - InnoDB error
+mariabackup.unencrypted_page_compressed : MDEV-18653 - Wrong error; include file modified in 10.5.7
mariabackup.xb_compressed_encrypted : MDEV-14812 - Segmentation fault
mariabackup.xb_file_key_management : MDEV-16571 - Wrong result
-mariabackup.xb_fulltext_encrypted : Modified in 10.5.4
mariabackup.xb_page_compress : MDEV-14810 - status: 1, errno: 11
-mariabackup.xb_partition : MDEV-17584 - Crash upon shutdown; modified in 10.5.4
+mariabackup.xb_partition : MDEV-17584 - Crash upon shutdown
mariabackup.xb_rocksdb : MDEV-17338 - Server hung on shutdown
#-----------------------------------------------------------------------
@@ -668,44 +611,27 @@ oqgraph.social : MDEV-22280 - Timeout
#-----------------------------------------------------------------------
-parts.alter_table : Modified in 10.5.5
-parts.debug_innodb_crash : Added in 10.5.4
-parts.debug_innodb_fail : Added in 10.5.4
-parts.debug_myisam_crash : Include file modified in 10.5.4
-parts.debug_myisam_fail : Added in 10.5.4
-parts.longname : Modified in 10.5.4
-parts.partition_alter1_1_2_innodb : MDEV-18655 - ASAN unknown crash
-parts.partition_alter1_1_innodb : MDEV-18655 - ASAN unknown crash
-parts.partition_alter1_2_innodb : MDEV-18655 - ASAN unknown crash
-parts.partition_alter2_2_maria : MDEV-14364 - Lost connection to MySQL server during query
-parts.partition_auto_increment_archive : MDEV-16491 - Marked as crashed and should be repaired; include file modified in 10.5.4
-parts.partition_auto_increment_blackhole : Include file modified in 10.5.4
-parts.partition_auto_increment_innodb : Include file modified in 10.5.4
-parts.partition_auto_increment_maria : MDEV-14430 - Extra warning; include file modified in 10.5.4
-parts.partition_auto_increment_memory : Include file modified in 10.5.4
-parts.partition_auto_increment_myisam : Include file modified in 10.5.4
-parts.partition_basic_innodb : MDEV-20214 - ASAN error
-parts.partition_debug : Modified in 10.5.5
-parts.partition_debug_innodb : MDEV-10891 - Can't create UNIX socket; MDEV-15095 - Table doesn't exist; modified in 10.5.4
-parts.partition_debug_myisam : Modified in 10.5.4
-parts.partition_exch_qa_10 : MDEV-11765 - wrong result
-parts.partition_innodb_status_file : MDEV-12901 - Valgrind
-parts.partition_special_innodb : MDEV-16942 - Timeout
-parts.percona_nonflushing_analyze_debug : Added in 10.5.4
-
-#-----------------------------------------------------------------------
-
-percona.* : MDEV-10997 - Not maintained
+parts.partition_alter1_1_2_innodb : MDEV-18655 - ASAN unknown crash
+parts.partition_alter1_1_innodb : MDEV-18655 - ASAN unknown crash
+parts.partition_alter1_2_innodb : MDEV-18655 - ASAN unknown crash
+parts.partition_alter2_2_maria : MDEV-14364 - Lost connection to MySQL server during query
+parts.partition_auto_increment_archive : MDEV-16491 - Marked as crashed and should be repaired
+parts.partition_auto_increment_maria : MDEV-14430 - Extra warning
+parts.partition_basic_innodb : MDEV-20214 - ASAN error
+parts.partition_debug_innodb : MDEV-10891 - Can't create UNIX socket; MDEV-15095 - Table doesn't exist
+parts.partition_exch_qa_10 : MDEV-11765 - wrong result
+parts.partition_innodb_status_file : MDEV-12901 - Valgrind
+parts.partition_special_innodb : MDEV-16942 - Timeout
+parts.reorganize : Added in 10.5.7
#-----------------------------------------------------------------------
perfschema.bad_option_1 : MDEV-21571 - Crash on bootstrap
perfschema.connect_attrs : MDEV-17283 - Wrong result
-perfschema.dml_file_instances : MDEV-15179 - Wrong result
+perfschema.dml_file_instances : MDEV-15179 - Wrong result; modified in 10.5.7
perfschema.dml_threads : MDEV-17746 - Wrong errno
perfschema.func_file_io : MDEV-5708 - fails for s390x
perfschema.func_mutex : MDEV-5708 - fails for s390x
-perfschema.grant : Added in 10.5.4
perfschema.hostcache_ipv4_addrinfo_again_allow : MDEV-12759 - Crash
perfschema.hostcache_ipv6_addrinfo_again_allow : MDEV-12752 - Crash
perfschema.hostcache_ipv6_addrinfo_bad_allow : MDEV-13260 - Crash
@@ -713,18 +639,18 @@ perfschema.hostcache_ipv6_ssl : MDEV-10696 - Crash
perfschema.memory_aggregate_no_a : MDEV-22949 - Wrong result
perfschema.memory_aggregate_no_a_no_h : MDEV-22949 - Wrong result
perfschema.memory_aggregate_no_a_no_u : MDEV-22949 - Wrong result
-perfschema.no_threads : Modified in 10.5.4
-perfschema.one_thread_per_con : Modified in 10.5.4
+perfschema.memory_aggregate_no_a_no_u_no_h : MDEV-22949 - Wrong result
+perfschema.nesting : MDEV-23458 - Wrong result
perfschema.pfs_upgrade_event : MDEV-20957 - Wrong result
perfschema.pfs_upgrade_func : MDEV-20957 - Upgrade file was not properly created
perfschema.pfs_upgrade_proc : MDEV-20533 - Upgrade file was not properly created
perfschema.pfs_upgrade_table : MDEV-20533 - Exec failed
perfschema.pfs_upgrade_view : MDEV-20533 - Upgrade file was not properly created
perfschema.privilege_table_io : MDEV-13184 - Extra lines
-perfschema.relaylog : MDEV-18134 - Wrong result
+perfschema.relaylog : MDEV-18134 - Wrong result; MDEV-24075 - Extra warning
perfschema.rpl_gtid_func : MDEV-16897 - Wrong result
perfschema.show_aggregate : MDEV-22962 - Wrong results
-perfschema.show_sanity : Modified in 10.5.4
+perfschema.show_sanity : Modified in 10.5.7
perfschema.socket_instances_func : MDEV-20140 - Wrong result
perfschema.socket_summary_by_event_name_func : MDEV-10622 - Wrong result
perfschema.socket_summary_by_instance_func : MDEV-19413 - Wrong result
@@ -733,10 +659,8 @@ perfschema.stage_mdl_global : MDEV-11803 - wrong result on sl
perfschema.stage_mdl_procedure : MDEV-11545 - Missing row
perfschema.stage_mdl_table : MDEV-12638 - Wrong result
perfschema.start_server_low_digest : MDEV-21221 - Wrong result
-perfschema.thread_cache : Modified in 10.5.4
perfschema.threads_history : MDEV-22948 - Wrong result
perfschema.threads_mysql : MDEV-10677 - Wrong result
-perfschema.transaction_nested_events : Modified in 10.5.4
#-----------------------------------------------------------------------
@@ -744,17 +668,17 @@ perfschema_stress.* : MDEV-10996 - Not maintained
#-----------------------------------------------------------------------
-period.engines : Combinations modified in 10.5.4
-period.overlaps : Modified in 10.5.4
-period.versioning : MDEV-20159 - Assertion failure; include file modified in 10.5.4
+period.delete : Modified in 10.5.7
+period.update : Modified in 10.5.7
+period.versioning : MDEV-20159 - Assertion failure
#-----------------------------------------------------------------------
-plugins.audit_null_debug : Modified in 10.5.5
plugins.feedback_plugin_send : MDEV-7932, MDEV-11118 - Connection problems and such
plugins.multiauth : MDEV-20163 - Plugin could not be loaded
plugins.processlist : MDEV-16574 - Wrong result
-plugins.server_audit : MDEV-14295 - Wrong result
+plugins.server_audit : MDEV-14295 - Wrong result; modified in 10.5.7
+plugins.test_sql_service : Added in 10.5.7
plugins.thread_pool_server_audit : MDEV-14295 - Wrong result
#-----------------------------------------------------------------------
@@ -794,129 +718,125 @@ rocksdb_sys_vars.rocksdb_rate_limiter_bytes_per_sec_basic : MDEV-16639 - Crash
#-----------------------------------------------------------------------
-roles.create_and_grant_role : MDEV-11772 - wrong result
-roles.drop_current_role : Added in 10.5.5
-roles.set_default_role_invalid : Modified in 10.5.4
-
-#-----------------------------------------------------------------------
-
-rpl.circular_serverid0 : MDEV-19372 - ASAN heap-use-after-free
-rpl.create_or_replace2 : MDEV-19412 - Lost connection to MySQL server
-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.parallel_backup : Added in 10.5.5
-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.5.5
-rpl.rpl_binlog_errors : MDEV-12742 - Crash
-rpl.rpl_binlog_grant : MDEV-21274 - Lost connection at handshake
-rpl.rpl_binlog_index : MDEV-9501 - Failed registering on master
-rpl.rpl_cant_read_event_incident : MDEV-20960 - Abort on shutdown
-rpl.rpl_checksum_cache : MDEV-22510 - Server crash
-rpl.rpl_circular_for_4_hosts : MDEV-20536 - Server crash
-rpl.rpl_colSize : MDEV-16112 - Server crash
-rpl.rpl_corruption : MDEV-20527 - Slave stopped with wrong error code
-rpl.rpl_create_tmp_table_if_not_exists : MDEV-20159 - Assertion failure
-rpl.rpl_ctype_latin1 : MDEV-14813 - Wrong result on Mac
-rpl.rpl_ddl : MDEV-10417 - Fails on Mips
-rpl.rpl_domain_id_filter_io_crash : MDEV-12729 - Timeout in include file, MDEV-13677 - Server crash
-rpl.rpl_domain_id_filter_master_crash : MDEV-19043 - Table marked as crashed
-rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result; MDEV-19043 - Table marked as crashed
-rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start
-rpl.rpl_dump_request_retry_warning : Added in 10.5.5
-rpl.rpl_extra_col_master_innodb : MDEV-16570 - Extra warning
-rpl.rpl_fail_register : Modified in 10.5.4
-rpl.rpl_flushlog_loop : MDEV-21570 - Server crash
-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 - Failed registering on master, MDEV-13643 - Lost connection
-rpl.rpl_gtid_delete_domain : MDEV-23103 - Could not delete gtid domain; MDEV-14463 - Timeout
-rpl.rpl_gtid_errorhandling : MDEV-13261 - Crash
-rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
-rpl.rpl_gtid_reconnect : MDEV-14497 - Crash
-rpl.rpl_gtid_startpos : MDEV-20141 - mysqltest failed but provided no output
-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_ignore_grant : MDEV-20159 - Assertion failure
-rpl.rpl_ignore_table_update : MDEV-20159 - Assertion failure
-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_ipv4_as_ipv6 : MDEV-20147 - Incorrect checksum for freed object
-rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog
-rpl.rpl_mdev12179 : MDEV-19043 - Table marked as crashed
-rpl.rpl_mdev6020 : MDEV-15272 - Server crash
-rpl.rpl_mixed_mixing_engines : MDEV-21266 - Timeout
-rpl.rpl_multi_engine : MDEV-23419 - Server crash
-rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master_pos_wait
-rpl.rpl_old_master : MDEV-22956 - Assertion failure
-rpl.rpl_parallel : MDEV-10653 - Timeouts
-rpl.rpl_parallel2 : MDEV-17390 - Operation cannot be performed; modified in 10.5.5
-rpl.rpl_parallel_conflicts : MDEV-15272 - Server crash
-rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure
-rpl.rpl_parallel_multilevel : MDEV-20160 - Server crash
-rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout
-rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master
-rpl.rpl_parallel_optimistic_nobinlog : MDEV-15278 - Failed to sync with master
-rpl.rpl_parallel_optimistic_until : MDEV-23021 - Query didn't return a result set; added in 10.5.4
-rpl.rpl_parallel_retry : MDEV-11119 - Crash; MDEV-17109 - Timeout
-rpl.rpl_parallel_temptable : MDEV-10356 - Crash; MDEV-19076 - Wrong result
-rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
-rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
-rpl.rpl_read_only : MDEV-20159 - Assertion failure
-rpl.rpl_row_001 : MDEV-16653 - MTR's internal check fails
-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_corruption : MDEV-21569 - mutex: LOCK_global_system_variables unlocking
-rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
-rpl.rpl_row_end_of_statement_loss : MDEV-21237 - Server crash
-rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
-rpl.rpl_row_img_eng_min : MDEV-13875 - 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_row_until : MDEV-14052 - Master will not send events with checksum
-rpl.rpl_row_virt : Added in 10.5.5
-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_skip_repl : MDEV-23371 - Server crash
-rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Assorted failures
-rpl.rpl_semi_sync_wait_no_slave : MDEV-20159 - Assertion failure
-rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
-rpl.rpl_semisync_ali_issues : MDEV-16272 - Wrong result
-rpl.rpl_show_slave_hosts : MDEV-10681 - Crash
-rpl.rpl_shutdown_wait_slaves : MDEV-22517 - Timeout on sync_with_master
-rpl.rpl_skip_replication : MDEV-23372 - Extra warning
-rpl.rpl_slave_alias_replica : Modified in 10.5.5
-rpl.rpl_slave_grp_exec : MDEV-10514 - Deadlock
-rpl.rpl_slave_load_in : MDEV-20159 - Assertion failure
-rpl.rpl_slow_query_log : MDEV-13250 - Test abort
-rpl.rpl_sp_effects : MDEV-13249 - Crash
-rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout
-rpl.rpl_stm_multi_query : MDEV-9501 - Failed registering on master
-rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
-rpl.rpl_stm_start_stop_slave : MDEV-23180 - ASAN heap-use-after-free
-rpl.rpl_stm_stop_middle_group : MDEV-13791 - Server crash
-rpl.rpl_sync : MDEV-10633 - Database page corruption
-rpl.rpl_temporal_mysql56_to_mariadb53 : MDEV-9501 - Failed registering on master
-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
-rpl.rpl_upgrade_master_info : MDEV-16567 - Assertion failure
-rpl.rpl_user_variables : MDEV-20522 - Wrong result
-rpl.rpl_variables : MDEV-20150 - Server crash
-rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result
-rpl.show_status_stop_slave_race-7126 : MDEV-17438 - Timeout
+roles.create_and_grant_role : MDEV-11772 - wrong result
+
+#-----------------------------------------------------------------------
+
+rpl.circular_serverid0 : MDEV-19372 - ASAN heap-use-after-free
+rpl.create_or_replace2 : MDEV-19412 - Lost connection to MySQL server
+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_errors : MDEV-12742 - Crash
+rpl.rpl_binlog_grant : MDEV-21274 - Lost connection at handshake
+rpl.rpl_binlog_index : Modified in 10.5.7
+rpl.rpl_cant_read_event_incident : MDEV-20960 - Abort on shutdown
+rpl.rpl_checksum_cache : MDEV-22510 - Server crash
+rpl.rpl_circular_for_4_hosts : MDEV-20536 - Server crash
+rpl.rpl_colSize : MDEV-16112 - Server crash
+rpl.rpl_corruption : MDEV-20527 - Slave stopped with wrong error code
+rpl.rpl_create_drop_view : Modified in 10.5.7
+rpl.rpl_create_tmp_table_if_not_exists : MDEV-20159 - Assertion failure
+rpl.rpl_ctype_latin1 : MDEV-14813 - Wrong result on Mac
+rpl.rpl_ddl : MDEV-10417 - Fails on Mips
+rpl.rpl_domain_id_filter_io_crash : MDEV-12729 - Timeout in include file, MDEV-13677 - Server crash
+rpl.rpl_domain_id_filter_master_crash : MDEV-19043 - Table marked as crashed
+rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result; MDEV-19043 - Table marked as crashed
+rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start
+rpl.rpl_extra_col_master_innodb : MDEV-16570 - Extra warning
+rpl.rpl_extra_col_master_myisam : MDEV-23372 - Extra warning
+rpl.rpl_filter_tables_dynamic : Modified in 10.5.7
+rpl.rpl_flushlog_loop : MDEV-21570 - Server crash
+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-13643 - Lost connection; modified in 10.5.7
+rpl.rpl_gtid_delete_domain : MDEV-23103 - Could not delete gtid domain; MDEV-14463 - Timeout; modified in 10.5.7
+rpl.rpl_gtid_errorhandling : MDEV-13261 - Crash
+rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
+rpl.rpl_gtid_reconnect : MDEV-14497 - Crash
+rpl.rpl_gtid_startpos : MDEV-20141 - mysqltest failed but provided no output
+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_ignore_grant : MDEV-20159 - Assertion failure
+rpl.rpl_ignore_table_update : MDEV-20159 - Assertion failure
+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_ipv4_as_ipv6 : MDEV-20147 - Incorrect checksum for freed object
+rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog
+rpl.rpl_mdev12179 : MDEV-19043 - Table marked as crashed
+rpl.rpl_mdev6020 : MDEV-23426 - Server crash, ASAN failures; MDEV-15272 - Server crash
+rpl.rpl_mixed_mixing_engines : MDEV-21266 - Timeout
+rpl.rpl_multi_engine : MDEV-23419 - Server crash
+rpl.rpl_mysql_upgrade : Modified in 10.5.7
+rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master_pos_wait
+rpl.rpl_old_master : MDEV-22956 - Assertion failure
+rpl.rpl_parallel : MDEV-10653 - Timeouts
+rpl.rpl_parallel2 : MDEV-17390 - Operation cannot be performed
+rpl.rpl_parallel_conflicts : MDEV-15272 - Server crash
+rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure
+rpl.rpl_parallel_multilevel : MDEV-20160 - Server crash
+rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout
+rpl.rpl_parallel_optimistic : MDEV-15278 - Failed to sync with master
+rpl.rpl_parallel_optimistic_nobinlog : MDEV-15278 - Failed to sync with master
+rpl.rpl_parallel_optimistic_until : MDEV-23021 - Query didn't return a result set
+rpl.rpl_parallel_retry : MDEV-11119 - Crash; MDEV-17109 - Timeout; modified in 10.5.7
+rpl.rpl_parallel_temptable : MDEV-10356 - Crash; MDEV-19076 - Wrong result
+rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
+rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
+rpl.rpl_read_only : MDEV-20159 - Assertion failure
+rpl.rpl_rewrt_db : MDEV-24060 - Server did not start
+rpl.rpl_row_001 : MDEV-16653 - MTR's internal check fails
+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_corruption : MDEV-21569 - mutex: LOCK_global_system_variables unlocking
+rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
+rpl.rpl_row_end_of_statement_loss : MDEV-21237 - Server crash
+rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_img_eng_min : MDEV-13875 - 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_row_until : MDEV-14052 - Master will not send events with checksum
+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_skip_repl : MDEV-23371 - Server crash
+rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Assorted failures
+rpl.rpl_semi_sync_wait_no_slave : MDEV-20159 - Assertion failure
+rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
+rpl.rpl_semisync_ali_issues : MDEV-16272 - Wrong result
+rpl.rpl_show_slave_hosts : MDEV-10681 - Crash
+rpl.rpl_shutdown_wait_slaves : MDEV-22517 - Timeout on sync_with_master
+rpl.rpl_skip_replication : MDEV-23372 - Extra warning
+rpl.rpl_slave_grp_exec : MDEV-10514 - Deadlock; re-enabled in 10.5.7; modified in 10.5.7
+rpl.rpl_slave_load_in : MDEV-20159 - Assertion failure
+rpl.rpl_slave_load_tmpdir_not_exist : MDEV-23372 - Extra warning
+rpl.rpl_slow_query_log : MDEV-13250 - Test abort
+rpl.rpl_sp_effects : MDEV-13249 - Crash
+rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout; modified in 10.5.7
+rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
+rpl.rpl_stm_start_stop_slave : MDEV-23180 - ASAN heap-use-after-free
+rpl.rpl_stm_stop_middle_group : MDEV-13791 - Server crash
+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
+rpl.rpl_upgrade_master_info : MDEV-16567 - Assertion failure
+rpl.rpl_user_variables : MDEV-20522 - Wrong result
+rpl.rpl_variables : MDEV-20150 - Server crash
+rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result
+rpl.show_status_stop_slave_race-7126 : Modified in 10.5.7
#-----------------------------------------------------------------------
@@ -924,11 +844,10 @@ rpl/extra/rpl_tests.* : MDEV-10994 - Not maintained
#-----------------------------------------------------------------------
-s3.* : Engine enabled in 10.5.4
-s3.alter2 : Modified in 10.5.4
-s3.replication_mixed : Include file modified in 10.5.4
-s3.replication_partition : Modified in 10.5.4
-s3.replication_stmt : Include file modified in 10.5.4
+s3.* : Configuration files modified in 10.5.7
+s3.alter : Modified in 10.5.7
+s3.replication_delayed : Added in 10.5.7
+s3.replication_partition : MDEV-24087 - Replication failure; modified in 10.5.7
#-----------------------------------------------------------------------
@@ -938,31 +857,24 @@ sphinx.union-5539 : MDEV-10986 - Sporadic failures
#-----------------------------------------------------------------------
-spider.* : MDEV-9329, MDEV-18737 - tests are too memory-consuming; include files modified in 10.5.4
-spider.basic_sql : MDEV-11186 - Internal check fails
-spider.slave_trx_isolation : Modified in 10.5.4
-spider.spider_wrapper_protocols : Added in 10.5.4
+spider.* : MDEV-9329, MDEV-18737 - tests are too memory-consuming
+spider.basic_sql : MDEV-11186 - Internal check fails
#-----------------------------------------------------------------------
-spider/bg.* : Include fieles modified in 10.5.4
-spider/bg.direct_aggregate : MDEV-7098 - Packets out of order
-spider/bg.direct_aggregate_part : MDEV-7098 - Trying to unlock mutex that wasn't locked
-spider/bg.ha : MDEV-9329 - failures on s390x
-spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x
-spider/bg.spider3_fixes : MDEV-12639 - Syntax error
-spider/bg.spider3_fixes_part : MDEV-7098 - Trying to unlock mutex
-spider/bg.spider_fixes : MDEV-7098 -Mutex problem, MDEV-9329 - failures on s390x
-spider/bg.spider_fixes_part : MDEV-7098 - Trying to unlock mutex that wasn't locked
-spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x
+spider/bg.* : MDEV-24059 - Timeout
+spider/bg.ha : MDEV-9329 - failures on s390x
+spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x
+spider/bg.spider3_fixes : MDEV-12639 - Syntax error
+spider/bg.spider_fixes : MDEV-9329 - failures on s390x
+spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x
#-----------------------------------------------------------------------
-spider/bugfix.* : Include fieles modified in 10.5.4
-spider/bugfix.insert_select : Added in 10.5.4
-spider/bugfix.self_reference : Added in 10.5.4
-spider/bugfix.slave_trx_isolation : Modified in 10.5.4
-spider/bugfix.strict_group_by : Added in 10.5.4
+spider/bugfix.direct_sql_with_comma_pwd : Added in 10.5.7
+spider/bugfix.mdev_20100 : Added in 10.5.7
+spider/bugfix.mdev_22246 : Added in 10.5.7
+spider/bugfix.xa_cmd : Added in 10.5.7
#-----------------------------------------------------------------------
@@ -970,10 +882,9 @@ spider/handler.* : MDEV-10987, MDEV-10990 - Tests have not been maintained
#-----------------------------------------------------------------------
-sql_sequence.alter : Modified in 10.5.4
sql_sequence.concurrent_create : MDEV-16635 - Server crash
-sql_sequence.create : Modified in 10.5.4
-sql_sequence.kill : MDEV-23393 - Server crash; added in 10.5.5
+sql_sequence.kill : MDEV-23393 - Server crash
+sql_sequence.next : Modified in 10.5.7
sql_sequence.read_only : MDEV-22956 - Failing assertion
#-----------------------------------------------------------------------
@@ -982,32 +893,29 @@ storage_engine.* : Tests are not always timely maintained
#-----------------------------------------------------------------------
-stress.* : Added to the main set in 10.5.4
stress.ddl_innodb : MDEV-10635 - Testcase timeout
-stress.misc : Added in 10.5.4
+stress.misc : MDEV-23420 - Server crash
#-----------------------------------------------------------------------
-sys_vars.all_vars : Modified in 10.5.4
sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x
sys_vars.host_cache_size_auto : MDEV-20112 - Wrong result
sys_vars.innodb_buffer_pool_dump_at_shutdown_basic : MDEV-14280 - Unexpected error
sys_vars.innodb_checksum_algorithm_basic : MDEV-21568 - Errno: 2000
-sys_vars.innodb_commit_concurrency_basic : Modified in 10.5.5
sys_vars.innodb_fatal_semaphore_wait_threshold : MDEV-22961 - Server failed to dissapear
+sys_vars.innodb_max_dirty_pages_pct_func : Modified in 10.5.7
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.5.4
-sys_vars.optimizer_switch_basic : Modified in 10.5.5
-sys_vars.rpl_init_slave_func : MDEV-10149 - Test assertion
-sys_vars.session_track_system_variables_basic : Modified in 10.5.5
+sys_vars.replicate_do_db_basic : Modified in 10.5.7
+sys_vars.rpl_init_slave_func : Modified in 10.5.7
+sys_vars.session_track_system_variables_basic : Modified in 10.5.7
sys_vars.slow_query_log_func : MDEV-14273 - Wrong result
sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result
-sys_vars.thread_pool_size_basic : Modified in 10.5.4
-sys_vars.wait_timeout_func : MDEV-12896 - Wrong result; modified in 10.5.4
+sys_vars.wait_timeout_func : MDEV-12896 - Wrong result
+sys_vars.wsrep_cluster_address_basic : Modified in 10.5.7
+sys_vars.wsrep_on_basic : Configuration deleted in 10.5.7
-type_inet.type_inet6 : Modified in 10.5.4
-type_inet.type_inet6_stat_tables : Modified in 10.5.4
+type_inet.type_inet6 : Modified in 10.5.7
#-----------------------------------------------------------------------
@@ -1025,36 +933,29 @@ unit.mf_iocache : MDEV-20952 - ASAN stack-buffer-overflow
vcol.not_supported : MDEV-10639 - Testcase timeout
vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout
-vcol.vcol_keys_myisam : Modified in 10.5.4
-vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.5.4
+vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.5.7
#-----------------------------------------------------------------------
-versioning.alter : Include file modified in 10.5.4
-versioning.auto_increment : Include file modified in 10.5.4
-versioning.commit_id : Include file modified in 10.5.4
-versioning.create : Include file modified in 10.5.4
-versioning.delete : Include file modified in 10.5.4
-versioning.delete_history : Include file modified in 10.5.4
-versioning.engines : Combinations modified in 10.5.4
-versioning.foreign : Include file modified in 10.5.4
-versioning.insert : Include file modified in 10.5.4
-versioning.online : Include file modified in 10.5.4
-versioning.partition : Modified in 10.5.5
-versioning.replace : MDEV-22960 - OS errors, crash; include file modified in 10.5.4
-versioning.select : Modified in 10.5.4
-versioning.select2 : Modified in 10.5.4
-versioning.sysvars : Modified in 10.5.5
-versioning.update : MDEV-22475 - Wrong result code; modified in 10.5.5
-versioning.update-big : Include file modified in 10.5.4
-versioning.view : Modified in 10.5.4
+versioning.create : Modified in 10.5.7
+versioning.replace : MDEV-22960 - OS errors, crash
+versioning.select : Modified in 10.5.7
+versioning.sysvars : Modified in 10.5.7
+versioning.update : MDEV-22475 - Wrong result code
+versioning.view : Modified in 10.5.7
#-----------------------------------------------------------------------
+wsrep.MDEV-22443 : Added in 10.5.7
+wsrep.MDEV-23081 : Added in 10.5.7
+wsrep.MDEV-23092 : Added in 10.5.7
+wsrep.MDEV-23466 : Added in 10.5.7
wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node
+wsrep.mdev_22681 : Added in 10.5.7
wsrep.mdev_6832 : MDEV-14195 - Check testcase failed
wsrep.pool_of_threads : MDEV-17345 - WSREP has not yet prepared node for application use
-wsrep.variables : MDEV-17585 - Deadlock
+wsrep.variables : Modified in 10.5.7
+wsrep.variables_debug : Added in 10.5.7
#-----------------------------------------------------------------------
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index e7fd75b5359..5b1a2608eeb 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -137,7 +137,7 @@ ENDIF()
ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
MAYBE_DISABLE_IPO(mysys)
TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY}
- ${LIBNSL} ${LIBM} ${LIBRT} ${LIBDL} ${LIBSOCKET} ${LIBEXECINFO})
+ ${LIBNSL} ${LIBM} ${LIBRT} ${CMAKE_DL_LIBS} ${LIBSOCKET} ${LIBEXECINFO})
DTRACE_INSTRUMENT(mysys)
IF(HAVE_BFD_H)
diff --git a/mysys/hash.c b/mysys/hash.c
index 87d714d6148..abc11b42500 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -792,14 +792,13 @@ void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record,
my_bool my_hash_iterate(HASH *hash, my_hash_walk_action action, void *argument)
{
uint records, i;
- HASH_LINK *data;
records= hash->records;
- data= dynamic_element(&hash->array,0,HASH_LINK*);
for (i= 0 ; i < records ; i++)
{
- if ((*action)(data[i].data, argument))
+ if ((*action)(dynamic_element(&hash->array, i, HASH_LINK *)->data,
+ argument))
return 1;
}
return 0;
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 75ff99b40a5..82ab6f20646 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -251,7 +251,7 @@ int init_io_cache_ext(IO_CACHE *info, File file, size_t cachesize,
info->write_buffer= info->buffer + cachesize;
else
info->write_buffer= info->buffer;
- info->alloced_buffer= 1;
+ info->alloced_buffer= buffer_block;
break; /* Enough memory found */
}
if (cachesize == min_cache)
@@ -321,14 +321,14 @@ int init_slave_io_cache(IO_CACHE *master, IO_CACHE *slave)
DBUG_ASSERT(!master->share);
DBUG_ASSERT(master->alloced_buffer);
- if (!(slave_buf= (uchar*)my_malloc(PSI_INSTRUMENT_ME, master->buffer_length, MYF(0))))
+ if (!(slave_buf= (uchar*)my_malloc(PSI_INSTRUMENT_ME, master->alloced_buffer, MYF(0))))
{
return 1;
}
memcpy(slave, master, sizeof(IO_CACHE));
slave->buffer= slave_buf;
- memcpy(slave->buffer, master->buffer, master->buffer_length);
+ memcpy(slave->buffer, master->buffer, master->alloced_buffer);
slave->read_pos= slave->buffer + (master->read_pos - master->buffer);
slave->read_end= slave->buffer + (master->read_end - master->buffer);
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 8cfeff1d6f0..bf2c89a9463 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -159,10 +159,18 @@ err:
#include <ctype.h>
#include <sys/wait.h>
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif /* defined(HAVE_POLL_H) */
+
static int in[2], out[2];
static pid_t pid;
static char addr2line_binary[1024];
static char output[1024];
+static struct pollfd poll_fds;
+Dl_info info;
int start_addr2line_fork(const char *binary_path)
{
@@ -214,12 +222,14 @@ static int addr_resolve(void *ptr, my_addr_loc *loc)
ssize_t extra_bytes_read = 0;
ssize_t parsed = 0;
- fd_set set;
- struct timeval timeout;
+ int ret;
int filename_start = -1;
int line_number_start = -1;
+ poll_fds.fd = out[0];
+ poll_fds.events = POLLIN | POLLRDBAND;
+
len= my_snprintf(input, sizeof(input), "%p\n", ptr);
if (write(in[1], input, len) <= 0)
{
@@ -228,16 +238,16 @@ static int addr_resolve(void *ptr, my_addr_loc *loc)
return 3;
}
- FD_ZERO(&set);
- FD_SET(out[0], &set);
- /* 100 ms should be plenty of time for addr2line to issue a response. */
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
+ /* 500 ms should be plenty of time for addr2line to issue a response. */
/* Read in a loop till all the output from addr2line is complete. */
while (parsed == total_bytes_read &&
- select(out[0] + 1, &set, NULL, NULL, &timeout) > 0)
+ (ret= poll(&poll_fds, 1, 500)))
{
+ /* error during poll */
+ if (ret < 0)
+ return 1;
+
extra_bytes_read= read(out[0], output + total_bytes_read,
sizeof(output) - total_bytes_read);
if (extra_bytes_read < 0)
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 4c3cd1435ac..106e51de581 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -104,7 +104,7 @@ const char *my_get_err_msg(uint nr)
@param MyFlags Flags
@param ... variable list matching that error format string
*/
-
+
void my_error(uint nr, myf MyFlags, ...)
{
const char *format;
@@ -112,7 +112,6 @@ void my_error(uint nr, myf MyFlags, ...)
char ebuff[ERRMSGSIZE];
DBUG_ENTER("my_error");
DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d", nr, MyFlags, errno));
-
if (!(format = my_get_err_msg(nr)))
(void) my_snprintf(ebuff, sizeof(ebuff), "Unknown error %d", nr);
else
diff --git a/mysys_ssl/openssl.c b/mysys_ssl/openssl.c
index e0f3d646ca9..b38d4ba309c 100644
--- a/mysys_ssl/openssl.c
+++ b/mysys_ssl/openssl.c
@@ -15,7 +15,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
-#include <ssl_compat.h>
/*
The check is only done for OpenSSL 1.1.x.
@@ -25,12 +24,14 @@
*/
#ifndef HAVE_OPENSSL11
+#include <ssl_compat.h>
int check_openssl_compatibility()
{
return 0;
}
#else
#include <openssl/evp.h>
+#include <ssl_compat.h>
static uint testing;
size_t alloc_size, alloc_count;
diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt
index 3c43d169d07..87c62812c39 100644
--- a/plugin/auth_gssapi/CMakeLists.txt
+++ b/plugin/auth_gssapi/CMakeLists.txt
@@ -18,6 +18,11 @@ ELSE()
SET(GSSAPI_SERVER gssapi_server.cc)
SET(GSSAPI_ERRMSG gssapi_errmsg.cc)
+ IF(APPLE)
+ SET_SOURCE_FILES_PROPERTIES(
+ ${GSSAPI_CLIENT} ${GSSAPI_SERVER} ${GSSAPI_ERRMSG}
+ PROPERTY COMPILE_FLAGS "-Wno-deprecated-declarations")
+ ENDIF()
SET(CMAKE_REQUIRED_INCLUDES ${GSSAPI_INCS})
SET(CMAKE_REQUIRED_LIBRARIES ${GSSAPI_LIBS})
SET(CMAKE_REQUIRED_FLAGS "-Werror -Wall")
diff --git a/plugin/auth_pam/CMakeLists.txt b/plugin/auth_pam/CMakeLists.txt
index 93ac29cd425..f7d8e019751 100644
--- a/plugin/auth_pam/CMakeLists.txt
+++ b/plugin/auth_pam/CMakeLists.txt
@@ -5,27 +5,35 @@ CHECK_INCLUDE_FILES (security/pam_ext.h HAVE_PAM_EXT_H)
CHECK_INCLUDE_FILES (security/pam_appl.h HAVE_PAM_APPL_H)
CHECK_FUNCTION_EXISTS (strndup HAVE_STRNDUP)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Check whether getgrouplist uses git_t for second and third arguments.
+SET(CMAKE_REQUIRED_FLAGS -Werror)
+CHECK_C_SOURCE_COMPILES(
+"
+#include <grp.h>
+#include <unistd.h>
+int main() {
+ char *arg_1= 0;
+ gid_t arg_2=0, arg_3;
+ int arg_4;
+ (void)getgrouplist(arg_1,arg_2,&arg_3,&arg_4);
+ return 0;
+}
+"
+HAVE_POSIX_GETGROUPLIST
+)
+SET(CMAKE_REQUIRED_FLAGS)
+
SET(CMAKE_REQUIRED_LIBRARIES pam)
CHECK_FUNCTION_EXISTS(pam_syslog HAVE_PAM_SYSLOG)
SET(CMAKE_REQUIRED_LIBRARIES)
-IF(HAVE_PAM_SYSLOG)
- ADD_DEFINITIONS(-DHAVE_PAM_SYSLOG)
-ENDIF()
-
-IF(HAVE_PAM_EXT_H)
- ADD_DEFINITIONS(-DHAVE_PAM_EXT_H)
-ENDIF()
-
IF(HAVE_PAM_APPL_H)
- ADD_DEFINITIONS(-DHAVE_PAM_APPL_H)
- IF(HAVE_STRNDUP)
- ADD_DEFINITIONS(-DHAVE_STRNDUP)
- ENDIF(HAVE_STRNDUP)
FIND_LIBRARY(PAM_LIBRARY pam) # for srpm build-depends detection
ADD_DEFINITIONS(-D_GNU_SOURCE)
MYSQL_ADD_PLUGIN(auth_pam_v1 auth_pam_v1.c LINK_LIBRARIES pam MODULE_ONLY)
- MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam ${LIBDL} MODULE_ONLY)
+ MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam ${CMAKE_DL_LIBS} MODULE_ONLY)
IF (TARGET auth_pam)
MYSQL_ADD_EXECUTABLE(auth_pam_tool auth_pam_tool.c DESTINATION ${INSTALL_PLUGINDIR}/auth_pam_tool_dir COMPONENT Server)
TARGET_LINK_LIBRARIES(auth_pam_tool pam)
@@ -47,3 +55,6 @@ IF(HAVE_PAM_APPL_H)
ENDIF()
ENDIF()
ENDIF(HAVE_PAM_APPL_H)
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/config_auth_pam.h)
diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c
index c1c05bba216..35272c6b7cd 100644
--- a/plugin/auth_pam/auth_pam.c
+++ b/plugin/auth_pam/auth_pam.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011, 2019, MariaDB Corporation.
+ Copyright (c) 2011, 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
@@ -15,6 +15,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
+#include <config_auth_pam.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
diff --git a/plugin/auth_pam/auth_pam_base.c b/plugin/auth_pam/auth_pam_base.c
index cdaafa58b98..1e8f4a08def 100644
--- a/plugin/auth_pam/auth_pam_base.c
+++ b/plugin/auth_pam/auth_pam_base.c
@@ -30,6 +30,7 @@
static int read_packet(struct param *param, unsigned char **pkt)
*/
+#include <config_auth_pam.h>
#include <stdio.h>
#include <string.h>
#include <security/pam_appl.h>
diff --git a/plugin/auth_pam/config.h.cmake b/plugin/auth_pam/config.h.cmake
new file mode 100644
index 00000000000..2a60e99d52c
--- /dev/null
+++ b/plugin/auth_pam/config.h.cmake
@@ -0,0 +1,5 @@
+#cmakedefine HAVE_POSIX_GETGROUPLIST 1
+#cmakedefine HAVE_PAM_SYSLOG 1
+#cmakedefine HAVE_PAM_EXT_H 1
+#cmakedefine HAVE_PAM_APPL_H 1
+#cmakedefine HAVE_STRNDUP 1
diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c
index 9d7ed53f8b1..fa8d9ae08c1 100644
--- a/plugin/auth_pam/mapper/pam_user_map.c
+++ b/plugin/auth_pam/mapper/pam_user_map.c
@@ -31,6 +31,7 @@ These comments are written to the syslog as 'authpriv.debug'
and usually end up in /var/log/secure file.
*/
+#include <config_auth_pam.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
@@ -70,10 +71,16 @@ pam_syslog (const pam_handle_t *pamh, int priority,
#define GROUP_BUFFER_SIZE 100
static const char debug_keyword[]= "debug";
-static int populate_user_groups(const char *user, gid_t **groups)
+#ifdef HAVE_POSIX_GETGROUPLIST
+typedef gid_t my_gid_t;
+#else
+typedef int my_gid_t;
+#endif
+
+static int populate_user_groups(const char *user, my_gid_t **groups)
{
- gid_t user_group_id;
- gid_t *loc_groups= *groups;
+ my_gid_t user_group_id;
+ my_gid_t *loc_groups= *groups;
int ng;
{
@@ -88,22 +95,23 @@ static int populate_user_groups(const char *user, gid_t **groups)
{
/* The rare case when the user is present in more than */
/* GROUP_BUFFER_SIZE groups. */
- loc_groups= (gid_t *) malloc(ng * sizeof (gid_t));
+ loc_groups= (my_gid_t *) malloc(ng * sizeof (my_gid_t));
+
if (!loc_groups)
return 0;
(void) getgrouplist(user, user_group_id, loc_groups, &ng);
- *groups= loc_groups;
+ *groups= (my_gid_t*)loc_groups;
}
return ng;
}
-static int user_in_group(const gid_t *user_groups, int ng,const char *group)
+static int user_in_group(const my_gid_t *user_groups, int ng,const char *group)
{
- gid_t group_id;
- const gid_t *groups_end = user_groups + ng;
+ my_gid_t group_id;
+ const my_gid_t *groups_end = user_groups + ng;
{
struct group *g= getgrnam(group);
@@ -122,7 +130,7 @@ static int user_in_group(const gid_t *user_groups, int ng,const char *group)
}
-static void print_groups(pam_handle_t *pamh, const gid_t *user_groups, int ng)
+static void print_groups(pam_handle_t *pamh, const my_gid_t *user_groups, int ng)
{
char buf[256];
char *c_buf= buf, *buf_end= buf+sizeof(buf)-2;
@@ -158,8 +166,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
const char *username;
char buf[256];
FILE *f;
- gid_t group_buffer[GROUP_BUFFER_SIZE];
- gid_t *groups= group_buffer;
+ my_gid_t group_buffer[GROUP_BUFFER_SIZE];
+ my_gid_t *groups= group_buffer;
int n_groups= -1;
for (; argc > 0; argc--)
diff --git a/plugin/auth_pam/testing/CMakeLists.txt b/plugin/auth_pam/testing/CMakeLists.txt
index 889cb524402..c8d2e3cbb97 100644
--- a/plugin/auth_pam/testing/CMakeLists.txt
+++ b/plugin/auth_pam/testing/CMakeLists.txt
@@ -4,6 +4,12 @@ ADD_LIBRARY(pam_mariadb_mtr MODULE pam_mariadb_mtr.c)
SET_TARGET_PROPERTIES (pam_mariadb_mtr PROPERTIES PREFIX "")
TARGET_LINK_LIBRARIES(pam_mariadb_mtr pam)
+IF(APPLE)
+ SET_SOURCE_FILES_PROPERTIES(
+ pam_mariadb_mtr.c
+ PROPERTY COMPILE_FLAGS "-Wno-incompatible-pointer-types-discards-qualifiers")
+ENDIF()
+
SET(dest DESTINATION "${INSTALL_MYSQLTESTDIR}/suite/plugins/pam" COMPONENT Test)
INSTALL(TARGETS pam_mariadb_mtr ${dest})
INSTALL(FILES mariadb_mtr.conf RENAME mariadb_mtr ${dest})
diff --git a/plugin/aws_key_management/aws_key_management_plugin.cc b/plugin/aws_key_management/aws_key_management_plugin.cc
index 348c171b618..7740c2eae60 100644
--- a/plugin/aws_key_management/aws_key_management_plugin.cc
+++ b/plugin/aws_key_management/aws_key_management_plugin.cc
@@ -162,6 +162,10 @@ public:
{
}
+ virtual void Flush(void) override
+ {
+ }
+
protected:
virtual void ProcessFormattedStatement(Aws::String&& statement) override
{
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 33e4d067766..bd630a16eb7 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -16,7 +16,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.8"
+#define PLUGIN_STR_VERSION "1.4.10"
#define _my_thread_var loc_thread_var
@@ -327,6 +327,10 @@ struct connection_info
char query_buffer[1024];
time_t query_time;
int log_always;
+ char proxy[64];
+ int proxy_length;
+ char proxy_host[64];
+ int proxy_host_length;
};
#define DEFAULT_FILENAME_LEN 16
@@ -1131,9 +1135,13 @@ static void setup_connection_simple(struct connection_info *ci)
ci->ip_length= 0;
ci->query_length= 0;
ci->header= 0;
+ ci->proxy_length= 0;
}
+#define MAX_HOSTNAME 61
+#define USERNAME_LENGTH 384
+
static void setup_connection_connect(struct connection_info *cn,
const struct mysql_event_connection *event)
{
@@ -1150,6 +1158,29 @@ static void setup_connection_connect(struct connection_info *cn,
get_str_n(cn->ip, &cn->ip_length, sizeof(cn->ip),
event->ip, event->ip_length);
cn->header= 0;
+ if (event->proxy_user && event->proxy_user[0])
+ {
+ const char *priv_host= event->proxy_user +
+ sizeof(char[MAX_HOSTNAME+USERNAME_LENGTH+5]);
+ size_t priv_host_length;
+
+ if (mysql_57_started)
+ {
+ priv_host+= sizeof(size_t);
+ priv_host_length= *(size_t *) (priv_host + MAX_HOSTNAME);
+ }
+ else
+ priv_host_length= strlen(priv_host);
+
+
+ get_str_n(cn->proxy, &cn->proxy_length, sizeof(cn->proxy),
+ event->priv_user, event->priv_user_length);
+ get_str_n(cn->proxy_host, &cn->proxy_host_length,
+ sizeof(cn->proxy_host),
+ priv_host, priv_host_length);
+ }
+ else
+ cn->proxy_length= 0;
}
@@ -1349,6 +1380,31 @@ static size_t log_header(char *message, size_t message_len,
}
+static int log_proxy(const struct connection_info *cn,
+ const struct mysql_event_connection *event)
+
+{
+ time_t ctime;
+ size_t csize;
+ char message[1024];
+
+ (void) time(&ctime);
+ csize= log_header(message, sizeof(message)-1, &ctime,
+ servhost, servhost_len,
+ cn->user, cn->user_length,
+ cn->host, cn->host_length,
+ cn->ip, cn->ip_length,
+ event->thread_id, 0, "PROXY_CONNECT");
+ csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize,
+ ",%.*s,`%.*s`@`%.*s`,%d", cn->db_length, cn->db,
+ cn->proxy_length, cn->proxy,
+ cn->proxy_host_length, cn->proxy_host,
+ event->status);
+ message[csize]= '\n';
+ return write_log(message, csize + 1, 1);
+}
+
+
static int log_connection(const struct connection_info *cn,
const struct mysql_event_connection *event,
const char *type)
@@ -2010,9 +2066,13 @@ static void update_connection_info(struct connection_info *cn,
{
case MYSQL_AUDIT_CONNECTION_CONNECT:
setup_connection_connect(cn, event);
+ if (event->status == 0 && event->proxy_user && event->proxy_user[0])
+ log_proxy(cn, event);
break;
case MYSQL_AUDIT_CONNECTION_CHANGE_USER:
*after_action= AA_CHANGE_USER;
+ if (event->proxy_user && event->proxy_user[0])
+ log_proxy(cn, event);
break;
default:;
}
diff --git a/plugin/test_sql_service/CMakeLists.txt b/plugin/test_sql_service/CMakeLists.txt
new file mode 100644
index 00000000000..aa9ecfe685e
--- /dev/null
+++ b/plugin/test_sql_service/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright (C) 2013 Alexey Botchkov and SkySQL Ab
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; 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
+
+SET(SOURCES test_sql_service.c)
+
+MYSQL_ADD_PLUGIN(test_sql_service ${SOURCES} MODULE_ONLY RECOMPILE_FOR_EMBEDDED)
diff --git a/plugin/test_sql_service/COPYING b/plugin/test_sql_service/COPYING
new file mode 100644
index 00000000000..6e475df5526
--- /dev/null
+++ b/plugin/test_sql_service/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/plugin/test_sql_service/test_sql_service.c b/plugin/test_sql_service/test_sql_service.c
new file mode 100644
index 00000000000..062f10fce58
--- /dev/null
+++ b/plugin/test_sql_service/test_sql_service.c
@@ -0,0 +1,145 @@
+/* Copyright (C) 2019, Alexey Botchkov and 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 */
+
+
+#define PLUGIN_VERSION 0x100
+#define PLUGIN_STR_VERSION "1.0.0"
+
+#define _my_thread_var loc_thread_var
+
+#include <my_config.h>
+#include <assert.h>
+#include <my_global.h>
+#include <my_base.h>
+#include <typelib.h>
+//#include <mysql_com.h> /* for enum enum_server_command */
+#include <mysql/plugin.h>
+#include <mysql/plugin_audit.h>
+//#include <string.h>
+
+
+LEX_STRING * thd_query_string (MYSQL_THD thd);
+unsigned long long thd_query_id(const MYSQL_THD thd);
+size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
+const char *thd_user_name(MYSQL_THD thd);
+const char *thd_client_host(MYSQL_THD thd);
+const char *thd_client_ip(MYSQL_THD thd);
+LEX_CSTRING *thd_current_db(MYSQL_THD thd);
+int thd_current_status(MYSQL_THD thd);
+enum enum_server_command thd_current_command(MYSQL_THD thd);
+
+int maria_compare_hostname(const char *wild_host, long wild_ip, long ip_mask,
+ const char *host, const char *ip);
+void maria_update_hostname(const char **wild_host, long *wild_ip, long *ip_mask,
+ const char *host);
+
+/* Status variables for SHOW STATUS */
+static long test_passed= 0;
+static struct st_mysql_show_var test_sql_status[]=
+{
+ {"test_sql_service_passed", (char *)&test_passed, SHOW_LONG},
+ {0,0,0}
+};
+
+static my_bool do_test= TRUE;
+static void run_test(MYSQL_THD thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+static MYSQL_SYSVAR_BOOL(run_test, do_test, PLUGIN_VAR_OPCMDARG,
+ "Perform the test now.", NULL, run_test, FALSE);
+static struct st_mysql_sys_var* test_sql_vars[]=
+{
+ MYSQL_SYSVAR(run_test),
+ NULL
+};
+
+
+extern int execute_sql_command(const char *command,
+ char *hosts, char *names, char *filters);
+
+
+
+static int do_tests()
+{
+ char plugins[1024];
+ char names[1024];
+ char dl[2048];
+ int result;
+
+ result= execute_sql_command("select 'plugin', name, dl from mysql.plugin",
+ plugins, names, dl);
+
+ return result;
+}
+
+
+void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
+{
+}
+
+
+static void run_test(MYSQL_THD thd __attribute__((unused)),
+ struct st_mysql_sys_var *var __attribute__((unused)),
+ void *var_ptr __attribute__((unused)),
+ const void *save __attribute__((unused)))
+{
+ test_passed= do_tests();
+}
+
+
+static int init_done= 0;
+
+static int test_sql_service_plugin_init(void *p __attribute__((unused)))
+{
+ init_done= 1;
+ return 0;
+}
+
+
+static int test_sql_service_plugin_deinit(void *p __attribute__((unused)))
+{
+ if (!init_done)
+ return 0;
+
+ return 0;
+}
+
+
+static struct st_mysql_audit maria_descriptor =
+{
+ MYSQL_AUDIT_INTERFACE_VERSION,
+ NULL,
+ auditing,
+ { MYSQL_AUDIT_GENERAL_CLASSMASK |
+ MYSQL_AUDIT_TABLE_CLASSMASK |
+ MYSQL_AUDIT_CONNECTION_CLASSMASK }
+};
+maria_declare_plugin(test_sql_service)
+{
+ MYSQL_AUDIT_PLUGIN,
+ &maria_descriptor,
+ "TEST_SQL_SERVICE",
+ "Alexey Botchkov (MariaDB Corporation)",
+ "Test SQL service",
+ PLUGIN_LICENSE_GPL,
+ test_sql_service_plugin_init,
+ test_sql_service_plugin_deinit,
+ PLUGIN_VERSION,
+ test_sql_status,
+ test_sql_vars,
+ PLUGIN_STR_VERSION,
+ MariaDB_PLUGIN_MATURITY_STABLE
+}
+maria_declare_plugin_end;
+
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result
index d8287363dc5..931c66fd9d2 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_plugin.result
@@ -24,7 +24,7 @@ PLUGIN_TYPE DATA TYPE
PLUGIN_AUTHOR MariaDB Corporation
PLUGIN_DESCRIPTION Data type INET6
PLUGIN_LICENSE GPL
-PLUGIN_MATURITY Alpha
+PLUGIN_MATURITY Beta
PLUGIN_AUTH_VERSION 1.0
#
# End of 10.5 tests
diff --git a/plugin/type_inet/plugin.cc b/plugin/type_inet/plugin.cc
index d7990b2bc5a..55052df80dd 100644
--- a/plugin/type_inet/plugin.cc
+++ b/plugin/type_inet/plugin.cc
@@ -186,7 +186,7 @@ maria_declare_plugin(type_inet)
NULL, // Status variables
NULL, // System variables
"1.0", // String version representation
- MariaDB_PLUGIN_MATURITY_ALPHA // Maturity(see include/mysql/plugin.h)*/
+ MariaDB_PLUGIN_MATURITY_BETA // Maturity(see include/mysql/plugin.h)*/
},
{
MariaDB_FUNCTION_PLUGIN, // the plugin type (see include/mysql/plugin.h)
diff --git a/plugin/type_mysql_json/CMakeLists.txt b/plugin/type_mysql_json/CMakeLists.txt
new file mode 100644
index 00000000000..ac0a1783012
--- /dev/null
+++ b/plugin/type_mysql_json/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright (c) 2020, MariaDB Foundation.
+#
+# This program is free 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
+
+MYSQL_ADD_PLUGIN(type_mysql_json
+ mysql_json.cc type.cc
+ MODULE_ONLY RECOMPILE_FOR_EMBEDDED)
diff --git a/plugin/type_mysql_json/mysql_json.cc b/plugin/type_mysql_json/mysql_json.cc
new file mode 100644
index 00000000000..4a75cae3909
--- /dev/null
+++ b/plugin/type_mysql_json/mysql_json.cc
@@ -0,0 +1,515 @@
+/*
+ Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2020 MariaDB Foundation
+
+
+ This program is free 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 "mysql_json.h"
+#include "my_global.h"
+#include "compat56.h"
+#include "my_decimal.h"
+#include "sql_time.h"
+
+static void TIME_from_longlong_date_packed(MYSQL_TIME *ltime, longlong tmp)
+{
+ TIME_from_longlong_datetime_packed(ltime, tmp);
+ ltime->time_type= MYSQL_TIMESTAMP_DATE;
+}
+
+
+/*
+ Json values in MySQL comprises the standard set of JSON values plus a MySQL
+ specific set. A JSON number type is subdivided into int, uint, double and
+ decimal.
+
+ MySQL also adds four built-in date/time values: date, time, datetime and
+ timestamp. An additional opaque value can store any other MySQL type.
+*/
+
+enum JSONB_LITERAL_TYPES {
+ JSONB_NULL_LITERAL= 0x0,
+ JSONB_TRUE_LITERAL= 0x1,
+ JSONB_FALSE_LITERAL= 0x2,
+};
+
+/*
+ The size of offset or size fields in the small and the large storage
+ format for JSON objects and JSON arrays.
+*/
+static const uchar SMALL_OFFSET_SIZE= 2;
+static const uchar LARGE_OFFSET_SIZE= 4;
+
+/*
+ The size of key entries for objects when using the small storage
+ format or the large storage format. In the small format it is 4
+ bytes (2 bytes for key length and 2 bytes for key offset). In the
+ large format it is 6 (2 bytes for length, 4 bytes for offset).
+*/
+static const uchar KEY_ENTRY_SIZE_SMALL= (2 + SMALL_OFFSET_SIZE);
+static const uchar KEY_ENTRY_SIZE_LARGE= (2 + LARGE_OFFSET_SIZE);
+
+/*
+ The size of value entries for objects or arrays. When using the
+ small storage format, the entry size is 3 (1 byte for type, 2 bytes
+ for offset). When using the large storage format, it is 5 (1 byte
+ for type, 4 bytes for offset).
+*/
+static const uchar VALUE_ENTRY_SIZE_SMALL= (1 + SMALL_OFFSET_SIZE);
+static const uchar VALUE_ENTRY_SIZE_LARGE= (1 + LARGE_OFFSET_SIZE);
+
+/* The maximum number of nesting levels allowed in a JSON document. */
+static const uchar JSON_DOCUMENT_MAX_DEPTH= 150;
+
+/**
+ Read an offset or size field from a buffer. The offset could be either
+ a two byte unsigned integer or a four byte unsigned integer.
+
+ @param data the buffer to read from
+ @param large tells if the large or small storage format is used; true
+ means read four bytes, false means read two bytes
+*/
+static inline size_t read_offset_or_size(const uchar *data, bool large)
+{
+ return large ? uint4korr(data) : uint2korr(data);
+}
+
+static inline size_t key_size(bool large)
+{
+ return large ? KEY_ENTRY_SIZE_LARGE : KEY_ENTRY_SIZE_SMALL;
+}
+
+static inline size_t value_size(bool large)
+{
+ return large ? VALUE_ENTRY_SIZE_LARGE : VALUE_ENTRY_SIZE_SMALL;
+}
+
+/**
+ Inlined values are a space optimization. The actual value is stored
+ instead of the offset pointer to the location where a non-inlined
+ value would be located.
+
+ @param[in] type The type to check.
+ @param[in] large tells if the large or small storage format is used;
+*/
+static inline bool type_is_stored_inline(JSONB_TYPES type, bool large)
+{
+ return (type == JSONB_TYPE_INT16 ||
+ type == JSONB_TYPE_UINT16 ||
+ type == JSONB_TYPE_LITERAL ||
+ (large && (type == JSONB_TYPE_INT32 ||
+ type == JSONB_TYPE_UINT32)));
+}
+
+/**
+ Read a variable length integer. A variable length integer uses the 8th bit in
+ each byte to mark if there are more bytes needed to store the integer. The
+ other 7 bits in the byte are used to store the actual integer's bits.
+
+ @param[in] data the buffer to read from
+ @param[in] data_length the maximum number of bytes to read from data
+ @param[out] length the length that was read
+ @param[out] num the number of bytes needed to represent the length
+ @return false on success, true on error
+*/
+static inline bool read_variable_length(const uchar *data, size_t data_length,
+ size_t *length, size_t *num)
+{
+ /*
+ It takes five bytes to represent UINT_MAX32, which is the largest
+ supported length, so don't look any further.
+
+ Use data_length as max value to prevent segfault when reading a corrupted
+ JSON document.
+ */
+ const size_t MAX_BYTES= MY_MIN(data_length, 5);
+ size_t len= 0;
+ for (size_t i= 0; i < MAX_BYTES; i++)
+ {
+ /* Get the next 7 bits of the length. */
+ len|= (data[i] & 0x7f) << (7 * i);
+ if ((data[i] & 0x80) == 0)
+ {
+ /* The length shouldn't exceed 32 bits. */
+ if (len > UINT_MAX32)
+ return true;
+
+ /* This was the last byte. Return successfully. */
+ *num= i + 1;
+ *length= len;
+ return false;
+ }
+ }
+
+ /* No more available bytes. Return true to signal error. This implies a
+ corrupted JSON document. */
+ return true;
+}
+
+/**
+ JSON formatting in MySQL escapes a few special characters to prevent
+ ambiguity.
+*/
+static bool append_string_json(String *buffer, const uchar *data, size_t len)
+{
+ const uchar *last= data + len;
+ for (; data < last; data++)
+ {
+ const uchar c= *data;
+ switch (c) {
+ case '\\':
+ buffer->append("\\\\");
+ break;
+ case '\n':
+ buffer->append("\\n");
+ break;
+ case '\r':
+ buffer->append("\\r");
+ break;
+ case '"':
+ buffer->append("\\\"");
+ break;
+ case '\b':
+ buffer->append("\\b");
+ break;
+ case '\f':
+ buffer->append("\\f");
+ break;
+ case '\t':
+ buffer->append("\\t");
+ break;
+ default:
+ buffer->append(c);
+ break;
+ }
+ }
+ return false;
+}
+
+/*
+ Function used for JSON_OPAQUE type.
+*/
+static bool print_mysql_datetime_value(String *buffer, enum_field_types type,
+ const uchar *data, size_t len)
+{
+ if (len < 8)
+ return true;
+
+ MYSQL_TIME t;
+ switch (type)
+ {
+ case MYSQL_TYPE_TIME:
+ TIME_from_longlong_time_packed(&t, sint8korr(data));
+ break;
+ case MYSQL_TYPE_DATE:
+ TIME_from_longlong_date_packed(&t, sint8korr(data));
+ break;
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ TIME_from_longlong_datetime_packed(&t, sint8korr(data));
+ break;
+ default:
+ DBUG_ASSERT(0);
+ return true;
+ }
+ /* Wrap all datetime strings within double quotes. */
+ buffer->append('\"');
+ buffer->reserve(MAX_DATE_STRING_REP_LENGTH);
+ buffer->length(buffer->length() +
+ my_TIME_to_str(&t, const_cast<char *>(buffer->end()), 6));
+ buffer->append('\"');
+ return false;
+}
+
+static bool parse_mysql_scalar(String *buffer, size_t value_json_type,
+ const uchar *data, size_t len)
+{
+ switch (value_json_type) {
+ case JSONB_TYPE_LITERAL:
+ {
+ if (len < 1)
+ return true;
+ switch (static_cast<JSONB_LITERAL_TYPES>(*data)) {
+ case JSONB_NULL_LITERAL:
+ return buffer->append("null");
+ case JSONB_TRUE_LITERAL:
+ return buffer->append("true");
+ case JSONB_FALSE_LITERAL:
+ return buffer->append("false");
+ default: /* Invalid literal constant, malformed JSON. */
+ return true;
+ }
+ }
+ case JSONB_TYPE_INT16:
+ return len < 2 || buffer->append_longlong(sint2korr(data));
+ case JSONB_TYPE_INT32:
+ return len < 4 || buffer->append_longlong(sint4korr(data));
+ case JSONB_TYPE_INT64:
+ return len < 8 || buffer->append_longlong(sint8korr(data));
+ case JSONB_TYPE_UINT16:
+ return len < 2 || buffer->append_ulonglong(uint2korr(data));
+ case JSONB_TYPE_UINT32:
+ return len < 4 || buffer->append_ulonglong(uint4korr(data));
+ case JSONB_TYPE_UINT64:
+ return len < 8 || buffer->append_ulonglong(uint8korr(data));
+ case JSONB_TYPE_DOUBLE:
+ if (len < 8)
+ return true;
+ buffer->reserve(FLOATING_POINT_BUFFER, 2 * FLOATING_POINT_BUFFER);
+ buffer->qs_append(reinterpret_cast<const double *>(data));
+ return false;
+ case JSONB_TYPE_STRING:
+ {
+ size_t string_length, store_bytes;
+
+ return read_variable_length(data, len, &string_length, &store_bytes) ||
+ len < store_bytes + string_length ||
+ buffer->append('"') ||
+ append_string_json(buffer, data + store_bytes, string_length) ||
+ buffer->append('"');
+ }
+ case JSONB_TYPE_OPAQUE:
+ {
+ /* The field_type maps directly to enum_field_types. */
+ const uchar type_value= *data;
+ const enum_field_types field_type= static_cast<enum_field_types>(type_value);
+
+ size_t UNINIT_VAR(blob_length), length_bytes;
+ const uchar *blob_start;
+
+ if (read_variable_length(data + 1, len, &blob_length, &length_bytes) ||
+ len < length_bytes + blob_length)
+ return true;
+ blob_start= data + length_bytes + 1;
+
+ switch (field_type) {
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ return print_mysql_datetime_value(buffer, field_type,
+ blob_start, blob_length);
+ case MYSQL_TYPE_NEWDECIMAL:
+ {
+ /* Expect at least two bytes, which contain precision and scale. */
+ if (blob_length < 2)
+ return true;
+
+ const int precision= blob_start[0];
+ const int scale= blob_start[1];
+
+ my_decimal d;
+
+ /* The decimal value is encoded after the two prec/scale bytes. */
+ const size_t dec_size= my_decimal_get_binary_size(precision, scale);
+ if (dec_size != blob_length - 2 ||
+ binary2my_decimal(E_DEC_ERROR,
+ reinterpret_cast<const uchar *>(blob_start + 2),
+ &d, precision, scale) != E_DEC_OK)
+ return true;
+
+ if (d.to_string_native(buffer, 0, 0, ' ', E_DEC_ERROR) != E_DEC_OK)
+ return true;
+ return false;
+ }
+ default:
+ {
+ /* Any other MySQL type is presented as a base64 encoded string. */
+ if (buffer->append("\"base64:type") ||
+ buffer->append_longlong(field_type) ||
+ buffer->append(':'))
+ return true;
+
+ const size_t needed= my_base64_needed_encoded_length(
+ static_cast<int>(blob_length));
+ if (buffer->reserve(needed) ||
+ my_base64_encode(blob_start, blob_length,
+ const_cast<char*>(buffer->end())))
+ return true;
+ /* -1 to override the null terminator from my_base64_encode */
+ DBUG_ASSERT(*(buffer->end() + needed) == '\0');
+ buffer->length(buffer->length() + needed - 1);
+ return buffer->append('"');
+ }
+ }
+ }
+ default:
+ return true;
+ }
+}
+
+
+/**
+ Read a value from a JSON Object or Array, given the position of it.
+ This function handles both inlined values as well as values stored at
+ an offset.
+
+ @param[out] buffer Where to print the results.
+ @param[in] data The raw binary data of the Object or Array.
+ @param[in] len The length of the binary data.
+ @param[in] value_type_offset Where the type of the value is stored.
+ @param[in] large true if the large storage format is used;
+ @param[in] depth How deep the JSON object is in the hierarchy.
+*/
+static bool parse_mysql_scalar_or_value(String *buffer, const uchar *data,
+ size_t len, size_t value_type_offset,
+ bool large, size_t depth)
+{
+ /* Get the type of the value stored at the key. */
+ const JSONB_TYPES value_type=
+ static_cast<JSONB_TYPES>(data[value_type_offset]);
+
+ if (type_is_stored_inline(value_type, large))
+ {
+ const size_t value_start = value_type_offset + 1;
+ if (parse_mysql_scalar(buffer, value_type, data + value_start,
+ len - value_start))
+ return true;
+ }
+ else
+ {
+ /* The offset to where the value is stored is relative to the start
+ of the Object / Array */
+ const size_t value_start= read_offset_or_size(
+ data + value_type_offset + 1, large);
+ if (parse_mysql_json_value(buffer, value_type, data + value_start,
+ len - value_start, depth))
+ return true;
+ }
+ return false;
+}
+
+static bool parse_array_or_object(String *buffer, const uchar *data, size_t len,
+ bool handle_as_object, bool large,
+ size_t depth)
+{
+ if (++depth > JSON_DOCUMENT_MAX_DEPTH)
+ return true;
+
+ /*
+ Make sure the document is long enough to contain the two length fields
+ (both number of elements or members, and number of bytes).
+ */
+ const size_t offset_size= large ? LARGE_OFFSET_SIZE : SMALL_OFFSET_SIZE;
+ /* The length has to be at least double offset size (header). */
+ if (len < 2 * offset_size)
+ return true;
+
+
+ /*
+ Every JSON Object or Array contains two numbers in the header:
+ - The number of elements in the Object / Array (Keys)
+ - The total number of bytes occupied by the JSON Object / Array, including
+ the two numbers in the header.
+ Depending on the Object / Array type (small / large) the numbers are stored
+ in 2 bytes or 4 bytes each.
+ */
+ const size_t element_count= read_offset_or_size(data, large);
+ const size_t bytes= read_offset_or_size(data + offset_size, large);
+
+ /* The value can't have more bytes than what's available in the buffer. */
+ if (bytes > len)
+ return true;
+
+ if (buffer->append(handle_as_object ? '{' : '['))
+ return true;
+
+
+ for (size_t i= 0; i < element_count; i++)
+ {
+ if (handle_as_object)
+ {
+ /*
+ The JSON Object is stored as a header part and a data part.
+ Header consists of:
+ - two length fields,
+ - an array of pointers to keys.
+ - an array of tuples (type, pointer to values)
+ * For certain types, the pointer to values is replaced by the actual
+ value. (see type_is_stored_inline)
+ Data consists of:
+ - All Key data, in order
+ - All Value data, in order
+ */
+ const size_t key_offset= 2 * offset_size + i * key_size(large);
+ const size_t key_start= read_offset_or_size(data + key_offset, large);
+ /* The length of keys is always stored in 2 bytes (large == false) */
+ const size_t key_len= read_offset_or_size(
+ data + key_offset + offset_size, false);
+
+ const size_t value_type_offset=(2 * offset_size +
+ element_count * key_size(large) +
+ i * value_size(large));
+
+ /* First print the key. */
+ if (buffer->append('"') ||
+ append_string_json(buffer, data + key_start, key_len) ||
+ buffer->append("\": "))
+ {
+ return true;
+ }
+
+ /* Then print the value. */
+ if (parse_mysql_scalar_or_value(buffer, data, bytes, value_type_offset,
+ large, depth))
+ return true;
+ }
+ else
+ {
+ /*
+ Arrays do not have the keys vector and its associated data.
+ We jump straight to reading values.
+ */
+ const size_t value_type_offset= 2 * offset_size + value_size(large) * i;
+
+ if (parse_mysql_scalar_or_value(buffer, data, bytes, value_type_offset,
+ large, depth))
+ return true;
+ }
+
+ if (i != element_count - 1 && buffer->append(", "))
+ return true;
+ }
+
+ return buffer->append(handle_as_object ? '}' : ']');
+}
+
+/**
+ Check the first byte of data which is the enum structure and based on it
+ perform parsing of object or array where each can have small or large
+ representation.
+
+ @param[out] buffer Where to print the results.
+ @param[in] type Type of value {object, array, scalar}.
+ @param[in] data Raw data for parsing.
+ @param[in] length Length of data.
+ @param[in] depth Depth size.
+*/
+bool parse_mysql_json_value(String *buffer, JSONB_TYPES type, const uchar *data,
+ size_t len, size_t depth)
+{
+ const bool IS_OBJECT=true, IS_LARGE=true;
+ switch (type) {
+ case JSONB_TYPE_SMALL_OBJECT:
+ return parse_array_or_object(buffer, data, len, IS_OBJECT, !IS_LARGE, depth);
+ case JSONB_TYPE_LARGE_OBJECT:
+ return parse_array_or_object(buffer, data, len, IS_OBJECT, IS_LARGE, depth);
+ case JSONB_TYPE_SMALL_ARRAY:
+ return parse_array_or_object(buffer, data, len, !IS_OBJECT, !IS_LARGE, depth);
+ case JSONB_TYPE_LARGE_ARRAY:
+ return parse_array_or_object(buffer, data, len, !IS_OBJECT, IS_LARGE, depth);
+ default:
+ return parse_mysql_scalar(buffer, type, data, len);
+ }
+}
diff --git a/plugin/type_mysql_json/mysql_json.h b/plugin/type_mysql_json/mysql_json.h
new file mode 100644
index 00000000000..afbacafc9c8
--- /dev/null
+++ b/plugin/type_mysql_json/mysql_json.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2020 MariaDB Foundation
+
+
+ This program is free 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 */
+
+#ifndef MYSQL_JSON_INCLUDED
+#define MYSQL_JSON_INCLUDED
+
+#include "my_global.h"
+#include "sql_string.h" // String
+
+enum JSONB_TYPES {
+ JSONB_TYPE_SMALL_OBJECT= 0x0,
+ JSONB_TYPE_LARGE_OBJECT= 0x1,
+ JSONB_TYPE_SMALL_ARRAY= 0x2,
+ JSONB_TYPE_LARGE_ARRAY= 0x3,
+ JSONB_TYPE_LITERAL= 0x4,
+ JSONB_TYPE_INT16= 0x5,
+ JSONB_TYPE_UINT16= 0x6,
+ JSONB_TYPE_INT32= 0x7,
+ JSONB_TYPE_UINT32= 0x8,
+ JSONB_TYPE_INT64= 0x9,
+ JSONB_TYPE_UINT64= 0xA,
+ JSONB_TYPE_DOUBLE= 0xB,
+ JSONB_TYPE_STRING= 0xC,
+ JSONB_TYPE_OPAQUE= 0xF
+};
+
+bool parse_mysql_json_value(String *buffer, JSONB_TYPES type, const uchar *data,
+ size_t len, size_t depth);
+
+#endif /* MYSQL_JSON_INCLUDED */
diff --git a/plugin/type_mysql_json/type.cc b/plugin/type_mysql_json/type.cc
new file mode 100644
index 00000000000..61507a24d92
--- /dev/null
+++ b/plugin/type_mysql_json/type.cc
@@ -0,0 +1,216 @@
+/*
+ Copyright (c) 2020 MariaDB Foundation
+
+ This program is free 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 <mysql/plugin_data_type.h>
+#include <my_global.h>
+#include <sql_type.h>
+#include <field.h>
+#include <mysqld_error.h>
+#include "mysql_json.h"
+
+const LEX_CSTRING empty_clex_str= {"", 0};
+
+class Type_handler_mysql_json: public Type_handler_blob
+{
+public:
+ Field *make_conversion_table_field(MEM_ROOT *, TABLE *, uint, const Field *)
+ const override;
+ const Type_collection *type_collection() const override;
+ Field *make_table_field_from_def(TABLE_SHARE *, MEM_ROOT *,
+ const LEX_CSTRING *, const Record_addr &,
+ const Bit_addr &,
+ const Column_definition_attributes *,
+ uint32) const override;
+ Field *make_table_field(MEM_ROOT *, const LEX_CSTRING *,
+ const Record_addr &, const Type_all_attributes &,
+ TABLE_SHARE *) const override;
+ void Column_definition_reuse_fix_attributes(THD *thd,
+ Column_definition *def,
+ const Field *field) const override;
+};
+
+Type_handler_mysql_json type_handler_mysql_json;
+
+
+class Field_mysql_json: public Field_blob
+{
+public:
+ Field_mysql_json(uchar *ptr_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg, TABLE_SHARE *share,
+ uint blob_pack_length, const DTCollation &collation)
+ : Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
+ field_name_arg, share, blob_pack_length,
+ &my_charset_utf8mb4_bin)
+ {}
+
+ String *val_str(String *val_buffer, String *val_str);
+ const Type_handler *type_handler() const { return &type_handler_mysql_json; }
+ bool parse_mysql(String *dest, const char *data, size_t length) const;
+ bool send(Protocol *protocol) { return Field::send(protocol); }
+ void sql_type(String &s) const
+ { s.set_ascii(STRING_WITH_LEN("json /* MySQL 5.7 */")); }
+ /* this will make ALTER TABLE to consider it different from built-in field */
+ Compression_method *compression_method() const { return (Compression_method*)1; }
+};
+
+Field *Type_handler_mysql_json::make_conversion_table_field(MEM_ROOT *root,
+ TABLE *table, uint metadata, const Field *target) const
+{
+ uint pack_length= metadata & 0x00ff;
+ if (pack_length < 1 || pack_length > 4)
+ return NULL; // Broken binary log?
+ return new (root)
+ Field_mysql_json(NULL, (uchar *) "", 1, Field::NONE, &empty_clex_str,
+ table->s, pack_length, target->charset());
+}
+
+Field *Type_handler_mysql_json::make_table_field_from_def(TABLE_SHARE *share,
+ MEM_ROOT *root, const LEX_CSTRING *name,
+ const Record_addr &addr, const Bit_addr &bit,
+ const Column_definition_attributes *attr, uint32 flags) const
+{
+ return new (root) Field_mysql_json(addr.ptr(), addr.null_ptr(),
+ addr.null_bit(), attr->unireg_check, name, share,
+ attr->pack_flag_to_pack_length(), attr->charset);
+}
+
+void Type_handler_mysql_json::
+ Column_definition_reuse_fix_attributes(THD *thd,
+ Column_definition *def,
+ const Field *field) const
+{
+ Type_handler_blob::Column_definition_reuse_fix_attributes(thd, def, field);
+ def->decimals= 0;
+}
+
+
+
+Field *Type_handler_mysql_json::make_table_field(MEM_ROOT *root,
+ const LEX_CSTRING *name, const Record_addr &addr,
+ const Type_all_attributes &attr, TABLE_SHARE *share) const
+{
+ return new (root) Field_mysql_json(addr.ptr(), addr.null_ptr(),
+ addr.null_bit(), Field::NONE, name, share, 2, attr.collation);
+}
+
+
+String *Field_mysql_json::val_str(String *val_buffer, String *val_ptr)
+{
+ String *raw_value= Field_blob::val_str(val_buffer, val_ptr);
+ String data;
+
+ data.copy(*raw_value);
+
+ val_ptr->length(0);
+ if (parse_mysql(val_ptr, data.ptr(), data.length()))
+ {
+ val_ptr->length(0);
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "Error parsing MySQL JSON format, please dump this table from MySQL "
+ "and then restore it to be able to use it in MariaDB.", MYF(0));
+ }
+ return val_ptr;
+}
+
+bool Field_mysql_json::parse_mysql(String *dest,
+ const char *data, size_t length) const
+{
+ if (!data)
+ return false;
+
+ /* Each JSON blob must start with a type specifier. */
+ if (length < 2)
+ return true;
+
+ if (parse_mysql_json_value(dest, static_cast<JSONB_TYPES>(data[0]),
+ reinterpret_cast<const uchar*>(data) + 1,
+ length - 1, 0))
+ return true;
+
+ return false;
+}
+
+class Type_collection_mysql_json: public Type_collection
+{
+public:
+ const Type_handler *aggregate_for_result(const Type_handler *a,
+ const Type_handler *b)
+ const override
+ {
+ if (a == b)
+ return a;
+ return NULL;
+ }
+
+ const Type_handler *aggregate_for_min_max(const Type_handler *a,
+ const Type_handler *b)
+ const override
+ {
+ return aggregate_for_result(a, b);
+ }
+
+ const Type_handler *aggregate_for_comparison(const Type_handler *a,
+ const Type_handler *b)
+ const override
+ {
+ return aggregate_for_result(a, b);
+ }
+
+ const Type_handler *aggregate_for_num_op(const Type_handler *a,
+ const Type_handler *b)
+ const override
+ {
+ return NULL;
+ }
+
+ const Type_handler *handler_by_name(const LEX_CSTRING &name) const override
+ {
+ if (type_handler_mysql_json.name().eq(name))
+ return &type_handler_mysql_json;
+ return NULL;
+ }
+};
+
+const Type_collection *Type_handler_mysql_json::type_collection() const
+{
+ static Type_collection_mysql_json type_collection_mysql_json;
+ return &type_collection_mysql_json;
+}
+
+static struct st_mariadb_data_type plugin_descriptor_type_mysql_json=
+{
+ MariaDB_DATA_TYPE_INTERFACE_VERSION,
+ &type_handler_mysql_json
+};
+
+maria_declare_plugin(type_mysql_json)
+{
+ MariaDB_DATA_TYPE_PLUGIN,
+ &plugin_descriptor_type_mysql_json,
+ "MYSQL_JSON",
+ "Anel Husaković, Vicențiu Ciorbaru",
+ "Data type MYSQL_JSON",
+ PLUGIN_LICENSE_GPL,
+ 0,
+ 0,
+ 0x0001,
+ NULL,
+ NULL,
+ "0.1",
+ MariaDB_PLUGIN_MATURITY_ALPHA
+}
+maria_declare_plugin_end;
diff --git a/scripts/convert-debug-for-diff.sh b/scripts/convert-debug-for-diff.sh
index 60b328d946b..5b3ce05b815 100755
--- a/scripts/convert-debug-for-diff.sh
+++ b/scripts/convert-debug-for-diff.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -i
+#!/usr/bin/perl -i
#
# This script converts all numbers that look like addresses or memory sizes,
# in a debug files generated by --debug (like mysqld --debug-dbug), to #.
diff --git a/scripts/mysql_config.pl.in b/scripts/mysql_config.pl.in
index fec9bc648f5..e161d4a1bee 100644
--- a/scripts/mysql_config.pl.in
+++ b/scripts/mysql_config.pl.in
@@ -201,7 +201,7 @@ $flags->{libs} =
$flags->{libs_r} =
[@ldflags,@lib_r_opts,'@ZLIB_DEPS@','@LIBS@','@openssl_libs@'];
$flags->{embedded_libs} =
- [@ldflags,@lib_e_opts,'@LIBDL@','@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@openssl_libs@'];
+ [@ldflags,@lib_e_opts,'@CMAKE_DL_LIBS@','@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@openssl_libs@'];
$flags->{include} = ["-I$pkgincludedir"];
$flags->{cflags} = [@{$flags->{include}},split(" ",'@CFLAGS@')];
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 423faa3320c..7b291811b30 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -646,18 +646,18 @@ ALTER TABLE db modify Delete_history_priv enum('N','Y') COLLATE utf8_general_ci
UPDATE user SET Delete_history_priv = Super_priv WHERE @had_user_delete_history_priv = 0;
-ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
- ADD authentication_string TEXT NOT NULL;
+ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL AFTER max_user_connections,
+ ADD authentication_string TEXT NOT NULL AFTER plugin;
ALTER TABLE user CHANGE auth_string authentication_string TEXT NOT NULL;
ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
MODIFY authentication_string TEXT NOT NULL;
-ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
+ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER authentication_string;
ALTER TABLE user ADD password_last_changed timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL after password_expired;
ALTER TABLE user ADD password_lifetime smallint unsigned DEFAULT NULL after password_last_changed;
ALTER TABLE user ADD account_locked enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL after password_lifetime;
-ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
-ALTER TABLE user ADD default_role char(80) binary DEFAULT '' NOT NULL;
-ALTER TABLE user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL;
+ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER account_locked;
+ALTER TABLE user ADD default_role char(80) binary DEFAULT '' NOT NULL AFTER is_role;
+ALTER TABLE user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL AFTER default_role;
-- Somewhere above, we ran ALTER TABLE user .... CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
-- we want password_expired column to have collation utf8_general_ci.
ALTER TABLE user MODIFY password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 0da86726bfb..c284e75a248 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -437,25 +437,10 @@ mysqld_ld_preload_text() {
echo "$text"
}
-
-mysql_config=
-get_mysql_config() {
- if [ -z "$mysql_config" ]; then
- mysql_config=`echo "$0" | sed 's,/[^/][^/]*$,/mysql_config,'`
- if [ ! -x "$mysql_config" ]; then
- log_error "Can not run mysql_config $@ from '$mysql_config'"
- exit 1
- fi
- fi
-
- "$mysql_config" "$@"
-}
-
-
# set_malloc_lib LIB
# - If LIB is empty, do nothing and return
-# - If LIB starts with 'tcmalloc' or 'jemalloc', look for the shared library in
-# /usr/lib, /usr/lib64 and then pkglibdir.
+# - If LIB starts with 'tcmalloc' or 'jemalloc', look for the shared library
+# using `ldconfig`.
# tcmalloc is part of the Google perftools project.
# - If LIB is an absolute path, assume it is a malloc shared library
#
@@ -463,28 +448,28 @@ get_mysql_config() {
# running mysqld. See ld.so for details.
set_malloc_lib() {
malloc_lib="$1"
-
if expr "$malloc_lib" : "\(tcmalloc\|jemalloc\)" > /dev/null ; then
- pkglibdir=`get_mysql_config --variable=pkglibdir`
- where=''
- # This list is kept intentionally simple. Simply set --malloc-lib
- # to a full path if another location is desired.
- for libdir in /usr/lib /usr/lib64 "$pkglibdir" "$pkglibdir/mysql"; do
- tmp=`echo "$libdir/lib$malloc_lib.so".[0-9]`
- where="$where $libdir"
- # log_notice "DEBUG: Checking for malloc lib '$tmp'"
- [ -r "$tmp" ] || continue
- malloc_lib="$tmp"
- where=''
- break
- done
+ if ! my_which ldconfig > /dev/null 2>&1
+ then
+ log_error "ldconfig command not found, required for ldconfig -p"
+ exit 1
+ fi
+ # format from ldconfig:
+ # "libjemalloc.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libjemalloc.so.1"
+ libmalloc_path="$(ldconfig -p | sed -n "/lib${malloc_lib}/p" | cut -d '>' -f2)"
- if [ -n "$where" ]; then
- log_error "no shared library for lib$malloc_lib.so.[0-9] found in$where"
+ if [ -z "$libmalloc_path" ]; then
+ log_error "no shared library for lib$malloc_lib.so.[0-9] found."
exit 1
fi
- fi
+ for f in $libmalloc_path; do
+ if [ -f "$f" ]; then
+ malloc_lib=$f # get the first path if many
+ break
+ fi
+ done
+ fi
# Allow --malloc-lib='' to override other settings
[ -z "$malloc_lib" ] && return
@@ -501,7 +486,6 @@ set_malloc_lib() {
exit 1
;;
esac
-
add_mysqld_ld_preload "$malloc_lib"
}
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 16607470f2c..5e134570881 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -45,28 +45,68 @@ case "$1" in
case "${WSREP_SST_OPT_ADDR}" in
\[*)
# IPv6
+ # Remove the starting and ending square brackets, if present:
addr_no_bracket=${WSREP_SST_OPT_ADDR#\[}
readonly WSREP_SST_OPT_HOST_UNESCAPED=${addr_no_bracket%%\]*}
+ # Square brackets are needed in most cases:
readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]"
+ # Some utilities and subsequent code require an address
+ # without square brackets:
readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]"
+ readonly WSREP_SST_OPT_HOST_IPv6=1
;;
*)
readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
readonly WSREP_SST_OPT_HOST_UNESCAPED=$WSREP_SST_OPT_HOST
readonly WSREP_SST_OPT_HOST_ESCAPED=$WSREP_SST_OPT_HOST
+ readonly WSREP_SST_OPT_HOST_IPv6=0
;;
esac
+ # Let's remove the leading part that contains the host address:
remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST_ESCAPED}}
+ # Let's remove the ":" character that separates the port number
+ # from the hostname:
remain=${remain#:}
+ # Extract the port number from the address - all characters
+ # up to "/" (if present):
readonly WSREP_SST_OPT_ADDR_PORT=${remain%%/*}
- remain=${remain#*/}
- readonly WSREP_SST_OPT_MODULE=${remain%%/*}
- readonly WSREP_SST_OPT_PATH=${WSREP_SST_OPT_ADDR#*/}
+ # If the "/" character is present, then the path is not empty:
+ if [ "${remain#*/}" != "${remain}" ]; then
+ # This operation removes everything up to the "/" character,
+ # effectively removing the port number from the string:
+ readonly WSREP_SST_OPT_PATH=${remain#*/}
+ else
+ readonly WSREP_SST_OPT_PATH=""
+ fi
+ # The rest of the string is the same as the path (for now):
+ remain=${WSREP_SST_OPT_PATH}
+ # If there is one more "/" in the string, then everything before
+ # it will be the module name, otherwise the module name is empty:
+ if [ "${remain%%/*}" != "${remain}" ]; then
+ # This operation removes the tail after the very first
+ # occurrence of the "/" character (inclusively):
+ readonly WSREP_SST_OPT_MODULE=${remain%%/*}
+ else
+ readonly WSREP_SST_OPT_MODULE=""
+ fi
+ # Remove the module name part from the string, which ends with "/":
remain=${WSREP_SST_OPT_PATH#*/}
+ # If the rest of the string does not match the original, then there
+ # was something else besides the module name:
if [ "$remain" != "${WSREP_SST_OPT_PATH}" ]; then
+ # Extract the part that matches the LSN by removing all
+ # characters starting from the very first "/":
readonly WSREP_SST_OPT_LSN=${remain%%/*}
+ # Exctract everything after the first occurrence of
+ # the "/" character in the string:
remain=${remain#*/}
+ # If the remainder does not match the original string,
+ # then there is something else (the version number in
+ # our case):
if [ "$remain" != "${WSREP_SST_OPT_LSN}" ]; then
+ # Let's extract the version number by removing the tail
+ # after the very first occurence of the "/" character
+ # (inclusively):
readonly WSREP_SST_OPT_SST_VER=${remain%%/*}
else
readonly WSREP_SST_OPT_SST_VER=""
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index 15e5ebeacf0..181cd45cf44 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -186,27 +186,48 @@ get_transfer()
if nc -h 2>&1 | grep -q ncat;then
# Ncat
tcmd="nc -l ${TSST_PORT}"
- elif nc -h 2>&1 | grep -q -- '-d\>';then
+ elif nc -h 2>&1 | grep -qw -- '-d\>';then
# Debian netcat
- tcmd="nc -dl ${TSST_PORT}"
+ if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then
+ # When host is not explicitly specified (when only the port
+ # is specified) netcat can only bind to an IPv4 address if
+ # the "-6" option is not explicitly specified:
+ tcmd="nc -dl -6 ${TSST_PORT}"
+ else
+ tcmd="nc -dl ${TSST_PORT}"
+ fi
else
# traditional netcat
tcmd="nc -l -p ${TSST_PORT}"
fi
else
+ # Check to see if netcat supports the '-N' flag.
+ # -N Shutdown the network socket after EOF on stdin
+ # If it supports the '-N' flag, then we need to use the '-N'
+ # flag, otherwise the transfer will stay open after the file
+ # transfer and cause the command to timeout.
+ # Older versions of netcat did not need this flag and will
+ # return an error if the flag is used.
+ #
+ tcmd_extra=""
+ if nc -h 2>&1 | grep -qw -- -N; then
+ tcmd_extra+="-N"
+ wsrep_log_info "Using nc -N"
+ fi
+
+ # netcat doesn't understand [] around IPv6 address
if nc -h 2>&1 | grep -q ncat;then
# Ncat
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
- elif nc -h 2>&1 | grep -q -- '-d\>';then
+ wsrep_log_info "Using Ncat as streamer"
+ tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
+ elif nc -h 2>&1 | grep -qw -- '-d\>';then
# Debian netcat
- if nc -h 2>&1 | grep -q -- '-N\>';then
- tcmd="nc -N ${REMOTEIP} ${TSST_PORT}"
- else
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
- fi
+ wsrep_log_info "Using Debian netcat as streamer"
+ tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
else
# traditional netcat
- tcmd="nc -q0 ${REMOTEIP} ${TSST_PORT}"
+ wsrep_log_info "Using traditional netcat as streamer"
+ tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
fi
fi
else
@@ -523,25 +544,11 @@ kill_xtrabackup()
setup_ports()
{
+ SST_PORT=${WSREP_SST_OPT_ADDR_PORT}
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
- if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then
- remain=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\][:/]' '{ print $2 }')
- REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\]:' '{ print $1 }')"]"
- SST_PORT=$(echo $remain | awk -F '[:/]' '{ print $1 }')
- lsn=$(echo $remain | awk -F '[:/]' '{ print $3 }')
- sst_ver=$(echo $remain | awk -F '[:/]' '{ print $4 }')
- else
- SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
- REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
- lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
- sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }')
- fi
- else
- if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $2 }')
- else
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
- fi
+ REMOTEIP=${WSREP_SST_OPT_HOST}
+ lsn=${WSREP_SST_OPT_LSN}
+ sst_ver=${WSREP_SST_OPT_SST_VER}
fi
}
@@ -701,9 +708,11 @@ if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; t
disver="--no-version-check"
fi
+iopts+=" --databases-exclude=\"lost+found\""
+
if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
- iopts+=" --no-backup-locks "
+ iopts+=" --no-backup-locks"
fi
INNOEXTRA=
diff --git a/sql-common/client.c b/sql-common/client.c
index 42ef5e24a75..95118fa1859 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2003, 2016, 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
@@ -3020,7 +3020,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* New protocol with 16 bytes to describe server characteristics */
mysql->server_language=end[2];
mysql->server_status=uint2korr(end+3);
- mysql->server_capabilities|= uint2korr(end+5) << 16;
+ mysql->server_capabilities|= ((unsigned) uint2korr(end+5)) << 16;
pkt_scramble_len= end[7];
if (pkt_scramble_len < 0)
{
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 4be129ac9d0..f6ddfbfaf38 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -193,7 +193,7 @@ DTRACE_INSTRUMENT(sql)
TARGET_LINK_LIBRARIES(sql
mysys mysys_ssl dbug strings vio pcre2-8
tpool
- ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT}
+ ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}
${SSL_LIBRARIES}
${LIBSYSTEMD})
diff --git a/sql/backup.cc b/sql/backup.cc
index 02570dfd30d..e89f9a108a7 100644
--- a/sql/backup.cc
+++ b/sql/backup.cc
@@ -378,7 +378,13 @@ bool backup_reset_alter_copy_lock(THD *thd)
bool backup_lock(THD *thd, TABLE_LIST *table)
{
+ /* We should leave the previous table unlocked in case of errors */
backup_unlock(thd);
+ if (thd->locked_tables_mode)
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ return 1;
+ }
table->mdl_request.duration= MDL_EXPLICIT;
if (thd->mdl_context.acquire_lock(&table->mdl_request,
thd->variables.lock_wait_timeout))
diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc
index 76fd736de2b..f48b95cbf76 100644
--- a/sql/derived_handler.cc
+++ b/sql/derived_handler.cc
@@ -120,8 +120,6 @@ void derived_handler::set_derived(TABLE_LIST *tbl)
table= tbl->table;
unit= tbl->derived;
select= unit->first_select();
- tmp_table_param= select->next_select() ?
- ((select_unit *)(unit->result))->get_tmp_table_param() :
- &select->join->tmp_table_param;
+ tmp_table_param= ((select_unit *)(unit->result))->get_tmp_table_param();
}
diff --git a/sql/field.h b/sql/field.h
index be4d279ce61..dfc02149f9d 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1151,8 +1151,9 @@ public:
virtual void reset_fields() {}
const uchar *ptr_in_record(const uchar *record) const
{
- my_ptrdiff_t l_offset= (my_ptrdiff_t) (record - table->record[0]);
- return ptr + l_offset;
+ my_ptrdiff_t l_offset= (my_ptrdiff_t) (ptr - table->record[0]);
+ DBUG_ASSERT(l_offset >= 0 && table->s->rec_buff_length - l_offset > 0);
+ return record + l_offset;
}
virtual int set_default();
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 2a713ecf97b..0337325b544 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -2208,6 +2208,12 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
length=0;
uint nullable_cols=0;
+ if (sort_keys->is_parameters_computed())
+ {
+ *allow_packing_for_sortkeys= sort_keys->using_packed_sortkeys();
+ return sort_keys->get_sort_length_with_memcmp_values();
+ }
+
for (SORT_FIELD *sortorder= sort_keys->begin();
sortorder != sort_keys->end();
sortorder++)
@@ -2218,12 +2224,11 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
{
Field *field= sortorder->field;
CHARSET_INFO *cs= sortorder->field->sort_charset();
- sortorder->set_length_and_original_length(thd, field->sort_length());
-
- sortorder->suffix_length= sortorder->field->sort_suffix_length();
sortorder->type= field->is_packable() ?
SORT_FIELD_ATTR::VARIABLE_SIZE :
SORT_FIELD_ATTR::FIXED_SIZE;
+ sortorder->set_length_and_original_length(thd, field->sort_length());
+ sortorder->suffix_length= sortorder->field->sort_suffix_length();
sortorder->cs= cs;
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
@@ -2242,11 +2247,11 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
}
else
{
- sortorder->item->type_handler()->sort_length(thd, sortorder->item,
- sortorder);
sortorder->type= sortorder->item->type_handler()->is_packable() ?
SORT_FIELD_ATTR::VARIABLE_SIZE :
SORT_FIELD_ATTR::FIXED_SIZE;
+ sortorder->item->type_handler()->sort_length(thd, sortorder->item,
+ sortorder);
sortorder->cs= sortorder->item->collation.collation;
if (sortorder->is_variable_sized() && allow_packing_for_keys)
{
@@ -2259,8 +2264,11 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
if ((sortorder->maybe_null= sortorder->item->maybe_null))
nullable_cols++; // Place for NULL marker
}
- set_if_smaller(sortorder->length, thd->variables.max_sort_length);
- set_if_smaller(sortorder->original_length, thd->variables.max_sort_length);
+ if (sortorder->is_variable_sized())
+ {
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
+ set_if_smaller(sortorder->original_length, thd->variables.max_sort_length);
+ }
length+=sortorder->length;
sort_keys->increment_size_of_packable_fields(sortorder->length_bytes);
@@ -2269,6 +2277,8 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
// add bytes for nullable_cols
sort_keys->increment_original_sort_length(nullable_cols);
*allow_packing_for_sortkeys= allow_packing_for_keys;
+ sort_keys->set_sort_length_with_memcmp_values(length + nullable_cols);
+ sort_keys->set_parameters_computed(true);
DBUG_PRINT("info",("sort_length: %d",length));
return length + nullable_cols;
}
@@ -2527,7 +2537,7 @@ void Sort_param::try_to_pack_sortkeys()
return;
const uint sz= Sort_keys::size_of_length_field;
- uint sort_len= sort_keys->get_sort_length();
+ uint sort_len= sort_keys->get_sort_length_with_original_values();
/*
Heuristic introduced, skip packing sort keys if saving less than 128 bytes
@@ -2759,7 +2769,8 @@ bool SORT_FIELD_ATTR::check_if_packing_possible(THD *thd) const
void SORT_FIELD_ATTR::set_length_and_original_length(THD *thd, uint length_arg)
{
length= length_arg;
- set_if_smaller(length, thd->variables.max_sort_length);
+ if (is_variable_sized())
+ set_if_smaller(length, thd->variables.max_sort_length);
original_length= length_arg;
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index ece9d05c4fd..7f00a194698 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2069,6 +2069,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
DBUG_ASSERT(part_elem->part_state == PART_TO_BE_REORGED);
part_elem->part_state= PART_TO_BE_DROPPED;
}
+ DBUG_ASSERT(m_new_file == 0);
m_new_file= new_file_array;
if (unlikely((error= copy_partitions(copied, deleted))))
{
@@ -2077,6 +2078,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
They will later be deleted through the ddl-log.
*/
cleanup_new_partition(part_count);
+ m_new_file= 0;
}
DBUG_RETURN(error);
}
@@ -2166,6 +2168,8 @@ int ha_partition::copy_partitions(ulonglong * const copied,
file->ha_rnd_end();
reorg_part++;
}
+ DBUG_EXECUTE_IF("debug_abort_copy_partitions",
+ DBUG_RETURN(HA_ERR_UNSUPPORTED); );
DBUG_RETURN(FALSE);
error:
m_reorged_file[reorg_part]->ha_rnd_end();
diff --git a/sql/handle_connections_win.cc b/sql/handle_connections_win.cc
index b12ea583230..debbce998fa 100644
--- a/sql/handle_connections_win.cc
+++ b/sql/handle_connections_win.cc
@@ -309,6 +309,64 @@ retry :
}
};
+/*
+ Create a security descriptor for pipe.
+ - Use low integrity level, so that it is possible to connect
+ from any process.
+ - Give current user read/write access to pipe.
+ - Give Everyone read/write access to pipe minus FILE_CREATE_PIPE_INSTANCE
+*/
+static void init_pipe_security_descriptor()
+{
+#define SDDL_FMT "S:(ML;; NW;;; LW) D:(A;; 0x%08x;;; WD)(A;; FRFW;;; %s)"
+#define EVERYONE_PIPE_ACCESS_MASK \
+ (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | \
+ SYNCHRONIZE | FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+
+#ifndef SECURITY_MAX_SID_STRING_CHARACTERS
+/* Old SDK does not have this constant */
+#define SECURITY_MAX_SID_STRING_CHARACTERS 187
+#endif
+
+ /*
+ Figure out SID of the user that runs the server, then create SDDL string
+ for pipe permissions, and convert it to the security descriptor.
+ */
+ char sddl_string[sizeof(SDDL_FMT) + 8 + SECURITY_MAX_SID_STRING_CHARACTERS];
+ struct
+ {
+ TOKEN_USER token_user;
+ BYTE buffer[SECURITY_MAX_SID_SIZE];
+ } token_buffer;
+ HANDLE token;
+ DWORD tmp;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
+ goto fail;
+
+ if (!GetTokenInformation(token, TokenUser, &token_buffer,
+ (DWORD) sizeof(token_buffer), &tmp))
+ goto fail;
+
+ CloseHandle(token);
+
+ char *current_user_string_sid;
+ if (!ConvertSidToStringSid(token_buffer.token_user.User.Sid,
+ &current_user_string_sid))
+ goto fail;
+
+ snprintf(sddl_string, sizeof(sddl_string), SDDL_FMT,
+ EVERYONE_PIPE_ACCESS_MASK, current_user_string_sid);
+ LocalFree(current_user_string_sid);
+
+ if (ConvertStringSecurityDescriptorToSecurityDescriptor(sddl_string,
+ SDDL_REVISION_1, &pipe_security.lpSecurityDescriptor, 0))
+ return;
+
+fail:
+ sql_perror("Can't start server : Initialize security descriptor");
+ unireg_abort(1);
+}
/**
Pipe Listener.
@@ -337,13 +395,7 @@ struct Pipe_Listener : public Listener
{
snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\%s", mysqld_unix_port);
open_mode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
- if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(
- "S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
- 1, &pipe_security.lpSecurityDescriptor, NULL))
- {
- sql_perror("Can't start server : Initialize security descriptor");
- unireg_abort(1);
- }
+ init_pipe_security_descriptor();
pipe_security.nLength= sizeof(SECURITY_ATTRIBUTES);
pipe_security.bInheritHandle= FALSE;
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 64d13d1601f..01825c13da6 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -188,7 +188,7 @@ private:
static int commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans,
- bool is_real_trans, bool rw_trans);
+ bool is_real_trans);
static plugin_ref ha_default_plugin(THD *thd)
@@ -1621,9 +1621,37 @@ int ha_commit_trans(THD *thd, bool all)
/* rw_trans is TRUE when we in a transaction changing data */
bool rw_trans= is_real_trans &&
(rw_ha_count > (thd->is_current_stmt_binlog_disabled()?0U:1U));
+ MDL_request mdl_backup;
DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d",
is_real_trans, rw_trans, rw_ha_count));
+ if (rw_trans)
+ {
+ /*
+ Acquire a metadata lock which will ensure that COMMIT is blocked
+ by an active FLUSH TABLES WITH READ LOCK (and vice versa:
+ COMMIT in progress blocks FTWRL).
+
+ We allow the owner of FTWRL to COMMIT; we assume that it knows
+ what it does.
+ */
+ MDL_REQUEST_INIT(&mdl_backup, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
+ MDL_EXPLICIT);
+
+ if (!WSREP(thd))
+ {
+ if (thd->mdl_context.acquire_lock(&mdl_backup,
+ thd->variables.lock_wait_timeout))
+ {
+ my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
+ ha_rollback_trans(thd, all);
+ DBUG_RETURN(1);
+ }
+ thd->backup_commit_lock= &mdl_backup;
+ }
+ DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
+ }
+
if (rw_trans &&
opt_readonly &&
!(thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY) &&
@@ -1663,7 +1691,7 @@ int ha_commit_trans(THD *thd, bool all)
// Here, the call will not commit inside InnoDB. It is only working
// around closing thd->transaction.stmt open by TR_table::open().
if (all)
- commit_one_phase_2(thd, false, &thd->transaction->stmt, false, false);
+ commit_one_phase_2(thd, false, &thd->transaction->stmt, false);
}
}
#endif
@@ -1683,7 +1711,7 @@ int ha_commit_trans(THD *thd, bool all)
goto wsrep_err;
}
#endif /* WITH_WSREP */
- error= ha_commit_one_phase(thd, all, rw_trans);
+ error= ha_commit_one_phase(thd, all);
#ifdef WITH_WSREP
// Here in case of error we must return 2 for inconsistency
if (run_wsrep_hooks && !error)
@@ -1720,7 +1748,7 @@ int ha_commit_trans(THD *thd, bool all)
if (!is_real_trans)
{
- error= commit_one_phase_2(thd, all, trans, is_real_trans, rw_trans);
+ error= commit_one_phase_2(thd, all, trans, is_real_trans);
goto done;
}
@@ -1754,7 +1782,7 @@ int ha_commit_trans(THD *thd, bool all)
DEBUG_SYNC(thd, "ha_commit_trans_after_log_and_order");
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
- error= commit_one_phase_2(thd, all, trans, is_real_trans, rw_trans) ? 2 : 0;
+ error= commit_one_phase_2(thd, all, trans, is_real_trans) ? 2 : 0;
#ifdef WITH_WSREP
if (run_wsrep_hooks &&
(error || (error = wsrep_after_commit(thd, all))))
@@ -1828,6 +1856,17 @@ err:
thd->rgi_slave->is_parallel_exec);
}
end:
+ if (mdl_backup.ticket)
+ {
+ /*
+ We do not always immediately release transactional locks
+ after ha_commit_trans() (see uses of ha_enable_transaction()),
+ thus we release the commit blocker lock as soon as it's
+ not needed.
+ */
+ thd->mdl_context.release_lock(mdl_backup.ticket);
+ }
+ thd->backup_commit_lock= 0;
#ifdef WITH_WSREP
if (wsrep_is_active(thd) && is_real_trans && !error &&
(rw_ha_count == 0 || all) &&
@@ -1842,8 +1881,8 @@ end:
/**
@note
- This function does not care about global read lock. A caller should.
- However backup locks are handled in commit_one_phase_2.
+ This function does not care about global read lock or backup locks,
+ the caller should.
@param[in] all Is set in case of explicit commit
(COMMIT statement), or implicit commit
@@ -1852,7 +1891,7 @@ end:
autocommit=1.
*/
-int ha_commit_one_phase(THD *thd, bool all, bool rw_trans)
+int ha_commit_one_phase(THD *thd, bool all)
{
THD_TRANS *trans=all ? &thd->transaction->all : &thd->transaction->stmt;
/*
@@ -1878,48 +1917,21 @@ int ha_commit_one_phase(THD *thd, bool all, bool rw_trans)
if ((res= thd->wait_for_prior_commit()))
DBUG_RETURN(res);
}
- res= commit_one_phase_2(thd, all, trans, is_real_trans, rw_trans);
+ res= commit_one_phase_2(thd, all, trans, is_real_trans);
DBUG_RETURN(res);
}
static int
-commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans,
- bool rw_trans)
+commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans)
{
int error= 0;
uint count= 0;
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
- MDL_request mdl_request;
- mdl_request.ticket= 0;
DBUG_ENTER("commit_one_phase_2");
if (is_real_trans)
DEBUG_SYNC(thd, "commit_one_phase_2");
- if (rw_trans)
- {
- /*
- Acquire a metadata lock which will ensure that COMMIT is blocked
- by an active FLUSH TABLES WITH READ LOCK (and vice versa:
- COMMIT in progress blocks FTWRL).
-
- We allow the owner of FTWRL to COMMIT; we assume that it knows
- what it does.
- */
- MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
- MDL_EXPLICIT);
-
- if (!WSREP(thd) &&
- thd->mdl_context.acquire_lock(&mdl_request,
- thd->variables.lock_wait_timeout))
- {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
- ha_rollback_trans(thd, all);
- DBUG_RETURN(1);
- }
- DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
- }
-
if (ha_info)
{
for (; ha_info; ha_info= ha_info_next)
@@ -1948,16 +1960,6 @@ commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans,
#endif
}
}
- if (mdl_request.ticket)
- {
- /*
- We do not always immediately release transactional locks
- after ha_commit_trans() (see uses of ha_enable_transaction()),
- thus we release the commit blocker lock as soon as it's
- not needed.
- */
- thd->mdl_context.release_lock(mdl_request.ticket);
- }
/* Free resources and perform other cleanup even for 'empty' transactions. */
if (is_real_trans)
@@ -2314,7 +2316,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
for (int i=0; i < got; i ++)
{
- my_xid x= IF_WSREP(WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ?
+ my_xid x= IF_WSREP(wsrep_is_wsrep_xid(&info->list[i]) ?
wsrep_xid_seqno(&info->list[i]) :
info->list[i].get_my_xid(),
info->list[i].get_my_xid());
@@ -2762,6 +2764,9 @@ int ha_delete_table(THD *thd, handlerton *hton, const char *path,
if (hton == NULL || hton == view_pseudo_hton)
DBUG_RETURN(0);
+ if (ha_check_if_updates_are_ignored(thd, hton, "DROP"))
+ DBUG_RETURN(0);
+
error= hton->drop_table(hton, path);
if (error > 0)
{
@@ -2799,7 +2804,8 @@ int ha_delete_table(THD *thd, handlerton *hton, const char *path,
error= -1;
}
}
-
+ if (error)
+ DBUG_PRINT("exit", ("error: %d", error));
DBUG_RETURN(error);
}
@@ -5006,7 +5012,8 @@ static my_bool delete_table_force(THD *thd, plugin_ref plugin, void *arg)
handlerton *hton = plugin_hton(plugin);
st_force_drop_table_params *param = (st_force_drop_table_params *)arg;
- if (param->discovering == (hton->discover_table != NULL))
+ if (param->discovering == (hton->discover_table != NULL) &&
+ !(thd->slave_thread && (hton->flags & HTON_IGNORE_UPDATES)))
{
int error;
error= ha_delete_table(thd, hton, param->path, param->db, param->alias, 0);
@@ -6316,6 +6323,7 @@ extern "C" check_result_t handler_index_cond_check(void* h_arg)
THD *thd= h->table->in_use;
check_result_t res;
+ DEBUG_SYNC(thd, "handler_index_cond_check");
enum thd_kill_levels abort_at= h->has_rollback() ?
THD_ABORT_SOFTLY : THD_ABORT_ASAP;
if (thd_kill_level(thd) > abort_at)
@@ -6349,6 +6357,7 @@ check_result_t handler_rowid_filter_check(void *h_arg)
if (!h->pushed_idx_cond)
{
THD *thd= h->table->in_use;
+ DEBUG_SYNC(thd, "handler_rowid_filter_check");
enum thd_kill_levels abort_at= h->has_transactions() ?
THD_ABORT_SOFTLY : THD_ABORT_ASAP;
if (thd_kill_level(thd) > abort_at)
@@ -6938,7 +6947,7 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data)
uchar *record_buffer= lookup_buffer + table_share->max_unique_length
+ table_share->null_fields;
- // Needs to compare record refs later is old_row_found()
+ // Needed to compare record refs later
if (is_update)
position(old_data);
@@ -6994,12 +7003,8 @@ int handler::ha_check_overlaps(const uchar *old_data, const uchar* new_data)
/* In case of update it could happen that the nearest neighbour is
a record we are updating. It means, that there are no overlaps
from this side.
-
- An assumption is made that during update we always have the last
- fetched row in old_data. Therefore, comparing ref's is enough
*/
DBUG_ASSERT(lookup_handler != this);
- DBUG_ASSERT(inited != NONE);
DBUG_ASSERT(ref_length == lookup_handler->ref_length);
lookup_handler->position(record_buffer);
@@ -7124,16 +7129,17 @@ int handler::ha_write_row(const uchar *buf)
if ((error= ha_check_overlaps(NULL, buf)))
DBUG_RETURN(error);
- MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
- mark_trx_read_write();
- increment_statistics(&SSV::ha_write_count);
-
if (table->s->long_unique_table && this == table->file)
{
DBUG_ASSERT(inited == NONE || lookup_handler != this);
if ((error= check_duplicate_long_entries(buf)))
DBUG_RETURN(error);
}
+
+ MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
+ mark_trx_read_write();
+ increment_statistics(&SSV::ha_write_count);
+
TABLE_IO_WAIT(tracker, PSI_TABLE_WRITE_ROW, MAX_KEY, error,
{ error= write_row(buf); })
@@ -7173,17 +7179,19 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
DBUG_ASSERT(new_data == table->record[0]);
DBUG_ASSERT(old_data == table->record[1]);
- if ((error= ha_check_overlaps(old_data, new_data)))
+ uint saved_status= table->status;
+ error= ha_check_overlaps(old_data, new_data);
+
+ if (!error && table->s->long_unique_table && this == table->file)
+ error= check_duplicate_long_entries_update(new_data);
+ table->status= saved_status;
+
+ if (error)
return error;
MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
mark_trx_read_write();
increment_statistics(&SSV::ha_update_count);
- if (table->s->long_unique_table && this == table->file &&
- (error= check_duplicate_long_entries_update(new_data)))
- {
- return error;
- }
TABLE_IO_WAIT(tracker, PSI_TABLE_UPDATE_ROW, active_index, 0,
{ error= update_row(old_data, new_data);})
@@ -8075,6 +8083,8 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_
TABLE_LIST &src_table, TABLE_LIST &table)
{
List_iterator<Create_field> it(alter_info.create_list);
+ List_iterator<Key> key_it(alter_info.key_list);
+ List_iterator<Key_part_spec> kp_it;
Create_field *f, *f_start=NULL, *f_end= NULL;
DBUG_ASSERT(alter_info.create_list.elements > 2);
@@ -8089,6 +8099,23 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_
it.remove();
remove--;
}
+ key_it.rewind();
+ while (Key *key= key_it++)
+ {
+ kp_it.init(key->columns);
+ while (Key_part_spec *kp= kp_it++)
+ {
+ if (0 == lex_string_cmp(system_charset_info, &kp->field_name,
+ &f->field_name))
+ {
+ kp_it.remove();
+ }
+ }
+ if (0 == key->columns.elements)
+ {
+ key_it.remove();
+ }
+ }
}
DBUG_ASSERT(remove == 0);
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
diff --git a/sql/handler.h b/sql/handler.h
index 9ab84794277..b106b460c70 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -5179,7 +5179,7 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
/* transactions: interface to handlerton functions */
int ha_start_consistent_snapshot(THD *thd);
int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
-int ha_commit_one_phase(THD *thd, bool all, bool rw_trans);
+int ha_commit_one_phase(THD *thd, bool all);
int ha_commit_trans(THD *thd, bool all);
int ha_rollback_trans(THD *thd, bool all);
int ha_prepare(THD *thd);
diff --git a/sql/item.h b/sql/item.h
index 19b7b5d03e9..fb480b4c578 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -120,20 +120,19 @@ enum precedence {
XOR_PRECEDENCE, // XOR
AND_PRECEDENCE, // AND, &&
NOT_PRECEDENCE, // NOT (unless HIGH_NOT_PRECEDENCE)
- BETWEEN_PRECEDENCE, // BETWEEN, CASE, WHEN, THEN, ELSE
- CMP_PRECEDENCE, // =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
+ CMP_PRECEDENCE, // =, <=>, >=, >, <=, <, <>, !=, IS
+ BETWEEN_PRECEDENCE, // BETWEEN
+ IN_PRECEDENCE, // IN, LIKE, REGEXP
BITOR_PRECEDENCE, // |
BITAND_PRECEDENCE, // &
SHIFT_PRECEDENCE, // <<, >>
- ADDINTERVAL_PRECEDENCE, // first argument in +INTERVAL
+ INTERVAL_PRECEDENCE, // first argument in +INTERVAL
ADD_PRECEDENCE, // +, -
MUL_PRECEDENCE, // *, /, DIV, %, MOD
BITXOR_PRECEDENCE, // ^
PIPES_PRECEDENCE, // || (if PIPES_AS_CONCAT)
- NEG_PRECEDENCE, // unary -, ~
- BANG_PRECEDENCE, // !, NOT (if HIGH_NOT_PRECEDENCE)
+ NEG_PRECEDENCE, // unary -, ~, !, NOT (if HIGH_NOT_PRECEDENCE)
COLLATE_PRECEDENCE, // BINARY, COLLATE
- INTERVAL_PRECEDENCE, // INTERVAL
DEFAULT_PRECEDENCE,
HIGHEST_PRECEDENCE
};
@@ -1716,6 +1715,8 @@ public:
mysql_register_view().
*/
virtual enum precedence precedence() const { return DEFAULT_PRECEDENCE; }
+ enum precedence higher_precedence() const
+ { return (enum precedence)(precedence() + 1); }
void print_parenthesised(String *str, enum_query_type query_type,
enum precedence parent_prec);
/**
@@ -5439,7 +5440,11 @@ public:
{
(*ref)->restore_to_before_no_rows_in_result();
}
- virtual void print(String *str, enum_query_type query_type);
+ void print(String *str, enum_query_type query_type);
+ enum precedence precedence() const
+ {
+ return ref ? (*ref)->precedence() : DEFAULT_PRECEDENCE;
+ }
void cleanup();
Item_field *field_for_view_update()
{ return (*ref)->field_for_view_update(); }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c753b963fd4..83eb605f463 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -868,6 +868,8 @@ int Arg_comparator::compare_decimal()
{
if (set_null)
owner->null_value= 0;
+ val1.round_self_if_needed((*a)->decimals, HALF_UP);
+ val2.round_self_if_needed((*b)->decimals, HALF_UP);
return val1.cmp(val2);
}
}
@@ -890,6 +892,8 @@ int Arg_comparator::compare_e_decimal()
VDec val1(*a), val2(*b);
if (val1.is_null() || val2.is_null())
return MY_TEST(val1.is_null() && val2.is_null());
+ val1.round_self_if_needed((*a)->decimals, HALF_UP);
+ val2.round_self_if_needed((*b)->decimals, HALF_UP);
return MY_TEST(val1.cmp(val2) == 0);
}
@@ -2331,7 +2335,7 @@ longlong Item_func_between::val_int_cmp_real()
void Item_func_between::print(String *str, enum_query_type query_type)
{
- args[0]->print_parenthesised(str, query_type, precedence());
+ args[0]->print_parenthesised(str, query_type, higher_precedence());
if (negated)
str->append(STRING_WITH_LEN(" not"));
str->append(STRING_WITH_LEN(" between "));
@@ -3348,27 +3352,28 @@ Item* Item_func_case_simple::propagate_equal_fields(THD *thd,
}
-void Item_func_case::print_when_then_arguments(String *str,
- enum_query_type query_type,
- Item **items, uint count)
+inline void Item_func_case::print_when_then_arguments(String *str,
+ enum_query_type
+ query_type,
+ Item **items, uint count)
{
- for (uint i=0 ; i < count ; i++)
+ for (uint i= 0; i < count; i++)
{
str->append(STRING_WITH_LEN("when "));
- items[i]->print_parenthesised(str, query_type, precedence());
+ items[i]->print(str, query_type);
str->append(STRING_WITH_LEN(" then "));
- items[i + count]->print_parenthesised(str, query_type, precedence());
+ items[i + count]->print(str, query_type);
str->append(' ');
}
}
-void Item_func_case::print_else_argument(String *str,
- enum_query_type query_type,
- Item *item)
+inline void Item_func_case::print_else_argument(String *str,
+ enum_query_type query_type,
+ Item *item)
{
str->append(STRING_WITH_LEN("else "));
- item->print_parenthesised(str, query_type, precedence());
+ item->print(str, query_type);
str->append(' ');
}
@@ -5600,12 +5605,14 @@ void Item_func_like::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN(" not "));
str->append(func_name());
str->append(' ');
- args[1]->print_parenthesised(str, query_type, precedence());
if (escape_used_in_parsing)
{
+ args[1]->print_parenthesised(str, query_type, precedence());
str->append(STRING_WITH_LEN(" escape "));
- escape_item->print(str, query_type);
+ escape_item->print_parenthesised(str, query_type, higher_precedence());
}
+ else
+ args[1]->print_parenthesised(str, query_type, higher_precedence());
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index fe6cba607a7..fa715badfc7 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,7 +1,7 @@
#ifndef ITEM_CMPFUNC_INCLUDED
#define ITEM_CMPFUNC_INCLUDED
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, 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
@@ -608,7 +608,7 @@ public:
enum Functype functype() const override { return NOT_FUNC; }
const char *func_name() const override { return "not"; }
bool find_not_null_fields(table_map allowed) override { return false; }
- enum precedence precedence() const override { return BANG_PRECEDENCE; }
+ enum precedence precedence() const override { return NEG_PRECEDENCE; }
Item *neg_transformer(THD *thd) override;
bool fix_fields(THD *, Item **) override;
void print(String *str, enum_query_type query_type) override;
@@ -2184,9 +2184,11 @@ protected:
bool aggregate_then_and_else_arguments(THD *thd, uint count);
virtual Item **else_expr_addr() const= 0;
virtual Item *find_item()= 0;
- void print_when_then_arguments(String *str, enum_query_type query_type,
- Item **items, uint count);
- void print_else_argument(String *str, enum_query_type query_type, Item *item);
+ inline void print_when_then_arguments(String *str,
+ enum_query_type query_type,
+ Item **items, uint count);
+ inline void print_else_argument(String *str, enum_query_type query_type,
+ Item *item);
void reorder_args(uint start);
public:
Item_func_case(THD *thd, List<Item> &list)
@@ -2202,7 +2204,6 @@ public:
bool fix_fields(THD *thd, Item **ref);
table_map not_null_tables() const { return 0; }
const char *func_name() const { return "case"; }
- enum precedence precedence() const { return BETWEEN_PRECEDENCE; }
CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
bool need_parentheses_in_default() { return true; }
};
@@ -2467,7 +2468,7 @@ public:
virtual void print(String *str, enum_query_type query_type);
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return "in"; }
- enum precedence precedence() const { return CMP_PRECEDENCE; }
+ enum precedence precedence() const { return IN_PRECEDENCE; }
bool eval_not_null_tables(void *opt_arg);
bool find_not_null_fields(table_map allowed);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
@@ -2793,7 +2794,7 @@ public:
return this;
}
const char *func_name() const { return "like"; }
- enum precedence precedence() const { return CMP_PRECEDENCE; }
+ enum precedence precedence() const { return IN_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
bool fix_length_and_dec()
{
@@ -2902,7 +2903,7 @@ public:
longlong val_int();
bool fix_length_and_dec();
const char *func_name() const { return "regexp"; }
- enum precedence precedence() const { return CMP_PRECEDENCE; }
+ enum precedence precedence() const { return IN_PRECEDENCE; }
Item *get_copy(THD *) { return 0; }
void print(String *str, enum_query_type query_type)
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 8a75d2c9946..027488e0279 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -640,8 +640,7 @@ void Item_func::print_op(String *str, enum_query_type query_type)
str->append(func_name());
str->append(' ');
}
- args[arg_count-1]->print_parenthesised(str, query_type,
- (enum precedence)(precedence() + 1));
+ args[arg_count-1]->print_parenthesised(str, query_type, higher_precedence());
}
@@ -1493,14 +1492,13 @@ double Item_func_div::real_op()
my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
{
int err;
- my_decimal tmp;
VDec2_lazy val(args[0], args[1]);
if ((null_value= val.has_null()))
return 0;
if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
~E_DEC_OVERFLOW &
~E_DEC_DIV_ZERO,
- &tmp,
+ decimal_value,
val.m_a.ptr(), val.m_b.ptr(),
prec_increment))) > 3)
{
@@ -1509,7 +1507,6 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
null_value= 1;
return 0;
}
- tmp.round_to(decimal_value, decimals, HALF_UP);
return decimal_value;
}
@@ -4017,6 +4014,8 @@ int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
timeout= m_abs_timeout;
error= mysql_cond_timedwait(cond, mutex, &timeout);
+ if (m_thd->check_killed())
+ break;
if (error == ETIMEDOUT || error == ETIME)
{
/* Return error if timed out or connection is broken. */
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 4acf1c6525b..f1a4ac4ef8a 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2003, 2016, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, MariaDB
+ Copyright (c) 2011, 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
@@ -443,16 +443,18 @@ String *Item_func_boundary::val_str(String *str_value)
DBUG_ASSERT(fixed == 1);
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
+
+ if ((null_value= args[0]->null_value))
+ DBUG_RETURN(0);
+
Geometry_buffer buffer;
- Geometry *g;
uint32 srid= 0;
Transporter trn(&res_receiver);
-
- if ((null_value=
- args[0]->null_value ||
- !(g= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))
+
+ Geometry *g= Geometry::construct(&buffer, swkb->ptr(), swkb->length());
+ if (!g)
DBUG_RETURN(0);
-
+
if (g->store_shapes(&trn))
goto mem_error;
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index aec3e1edcd3..032ecb1bb91 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -2464,6 +2464,8 @@ String *Item_func_json_merge_patch::val_str(String *str)
uint n_arg;
bool empty_result, merge_to_null;
+ /* To report errors properly if some JSON is invalid. */
+ je1.s.error= je2.s.error= 0;
merge_to_null= args[0]->null_value;
for (n_arg=1; n_arg < arg_count; n_arg++)
@@ -3772,6 +3774,8 @@ Item_func_json_objectagg::fix_fields(THD *thd, Item **ref)
uint i; /* for loop variable */
DBUG_ASSERT(fixed == 0);
+ memcpy(orig_args, args, sizeof(Item*) * arg_count);
+
if (init_sum_func_check(thd))
return TRUE;
@@ -3867,7 +3871,3 @@ String* Item_func_json_objectagg::val_str(String* str)
}
-void Item_func_json_objectagg::print(String *str, enum_query_type query_type)
-{
-}
-
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 6bd2a81afc6..ec6c6696001 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -589,7 +589,7 @@ public:
void cleanup();
enum Sumfunctype sum_func () const {return JSON_OBJECTAGG_FUNC;}
- const char *func_name() const { return "json_objectagg("; }
+ const char *func_name() const { return "json_objectagg"; }
const Type_handler *type_handler() const
{
if (too_big_for_varchar())
@@ -618,7 +618,6 @@ public:
String* val_str(String* str);
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
- void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_json_objectagg>(thd, this); }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 334fec2e048..cbde9599073 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -3357,7 +3357,7 @@ void Item_in_subselect::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN("<exists>"));
else
{
- left_expr->print(str, query_type);
+ left_expr->print_parenthesised(str, query_type, precedence());
str->append(STRING_WITH_LEN(" in "));
}
Item_subselect::print(str, query_type);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 7e504d09565..ec4398b9a76 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -640,7 +640,7 @@ public:
bool val_bool() override;
bool test_limit(st_select_lex_unit *unit);
void print(String *str, enum_query_type query_type) override;
- enum precedence precedence() const override { return CMP_PRECEDENCE; }
+ enum precedence precedence() const override { return IN_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref) override;
bool fix_length_and_dec() override;
void fix_after_pullout(st_select_lex *new_parent, Item **ref,
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 6b5c6fa323c..b8650a5c7e9 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2095,9 +2095,9 @@ static const char *interval_names[]=
void Item_date_add_interval::print(String *str, enum_query_type query_type)
{
- args[0]->print_parenthesised(str, query_type, ADDINTERVAL_PRECEDENCE);
+ args[0]->print_parenthesised(str, query_type, INTERVAL_PRECEDENCE);
str->append(date_sub_interval?" - interval ":" + interval ");
- args[1]->print_parenthesised(str, query_type, INTERVAL_PRECEDENCE);
+ args[1]->print(str, query_type);
str->append(' ');
str->append(interval_names[int_type]);
}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 35c9df533c4..a910b2cb723 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -948,7 +948,7 @@ public:
bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
- enum precedence precedence() const { return ADDINTERVAL_PRECEDENCE; }
+ enum precedence precedence() const { return INTERVAL_PRECEDENCE; }
bool need_parentheses_in_default() { return true; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_date_add_interval>(thd, this); }
diff --git a/sql/log.cc b/sql/log.cc
index 2a887a68606..2dd1a3a45ab 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -601,9 +601,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 */
@@ -1355,7 +1357,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, size_t query_length,
my_hrtime_t current_time= { hrtime_from_time(thd->start_time) +
thd->start_time_sec_part + query_utime };
- if (!query)
+ if (!query || thd->get_command() == COM_STMT_PREPARE)
{
is_command= TRUE;
query= command_name[thd->get_command()].str;
@@ -2151,6 +2153,12 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
DBUG_RETURN(0);
}
+ /*
+ This is true if we are doing an alter table that is replicated as
+ CREATE TABLE ... SELECT
+ */
+ if (thd->variables.option_bits & OPTION_BIN_COMMIT_OFF)
+ DBUG_RETURN(0);
DBUG_PRINT("debug",
("all: %d, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
@@ -6574,11 +6582,26 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
if (direct)
{
+ /* We come here only for incident events */
int res;
uint64 commit_id= 0;
+ MDL_request mdl_request;
DBUG_PRINT("info", ("direct is set"));
+ DBUG_ASSERT(!thd->backup_commit_lock);
+
+ MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
+ MDL_EXPLICIT);
+ thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout);
+ thd->backup_commit_lock= &mdl_request;
+
if ((res= thd->wait_for_prior_commit()))
+ {
+ if (mdl_request.ticket)
+ thd->mdl_context.release_lock(mdl_request.ticket);
+ thd->backup_commit_lock= 0;
DBUG_RETURN(res);
+ }
file= &log_file;
my_org_b_tell= my_b_tell(file);
mysql_mutex_lock(&LOCK_log);
@@ -6593,7 +6616,11 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
commit_name.length);
commit_id= entry->val_int(&null_value);
});
- if (write_gtid_event(thd, true, using_trans, commit_id))
+ res= write_gtid_event(thd, true, using_trans, commit_id);
+ if (mdl_request.ticket)
+ thd->mdl_context.release_lock(mdl_request.ticket);
+ thd->backup_commit_lock= 0;
+ if (res)
goto err;
}
else
@@ -7657,7 +7684,11 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
group_commit_entry *entry, *orig_queue, *last;
wait_for_commit *cur;
wait_for_commit *wfc;
+ bool backup_lock_released= 0;
+ int result= 0;
+ THD *thd= orig_entry->thd;
DBUG_ENTER("MYSQL_BIN_LOG::queue_for_group_commit");
+ DBUG_ASSERT(thd == current_thd);
/*
Check if we need to wait for another transaction to commit before us.
@@ -7689,6 +7720,21 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
{
PSI_stage_info old_stage;
+ /*
+ Release MDL_BACKUP_COMMIT LOCK while waiting for other threads to
+ commit.
+ This is needed to avoid deadlock between the other threads (which not
+ yet have the MDL_BACKUP_COMMIT_LOCK) and any threads using
+ BACKUP LOCK BLOCK_COMMIT.
+ */
+ if (thd->backup_commit_lock && thd->backup_commit_lock->ticket &&
+ !backup_lock_released)
+ {
+ backup_lock_released= 1;
+ thd->mdl_context.release_lock(thd->backup_commit_lock->ticket);
+ thd->backup_commit_lock->ticket= 0;
+ }
+
/*
By setting wfc->opaque_pointer to our own entry, we mark that we are
ready to commit, but waiting for another transaction to commit before
@@ -7749,7 +7795,8 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
wfc->wakeup_error= ER_QUERY_INTERRUPTED;
my_message(wfc->wakeup_error,
ER_THD(orig_entry->thd, wfc->wakeup_error), MYF(0));
- DBUG_RETURN(-1);
+ result= -1;
+ goto end;
}
}
orig_entry->thd->EXIT_COND(&old_stage);
@@ -7763,12 +7810,13 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
then there is nothing else to do.
*/
if (orig_entry->queued_by_other)
- DBUG_RETURN(0);
+ goto end;
if (wfc && wfc->wakeup_error)
{
my_error(ER_PRIOR_COMMIT_FAILED, MYF(0));
- DBUG_RETURN(-1);
+ result= -1;
+ goto end;
}
/* Now enqueue ourselves in the group commit queue. */
@@ -7929,7 +7977,13 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
DBUG_PRINT("info", ("Queued for group commit as %s",
(orig_queue == NULL) ? "leader" : "participant"));
- DBUG_RETURN(orig_queue == NULL);
+ result= orig_queue == NULL;
+
+end:
+ if (backup_lock_released)
+ thd->mdl_context.acquire_lock(thd->backup_commit_lock,
+ thd->variables.lock_wait_timeout);
+ DBUG_RETURN(result);
}
bool
@@ -10753,7 +10807,8 @@ binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var,
}
-static int show_binlog_vars(THD *thd, SHOW_VAR *var, char *buff)
+static int show_binlog_vars(THD *thd, SHOW_VAR *var, void *,
+ system_status_var *status_var, enum_var_type)
{
mysql_bin_log.set_status_variables(thd);
var->type= SHOW_ARRAY;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d66ece96eba..0388a2b19b1 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1074,7 +1074,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
diff --git a/sql/log_event.h b/sql/log_event.h
index 222e611ecae..4e193232f4b 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -2227,8 +2227,10 @@ public:
virtual bool is_commit() { return false; }
virtual bool is_rollback() { return false; }
#ifdef MYSQL_SERVER
- Query_compressed_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
- bool using_trans, bool direct, bool suppress_use, int error);
+ Query_compressed_log_event(THD* thd_arg, const char* query_arg,
+ ulong query_length,
+ bool using_trans, bool direct, bool suppress_use,
+ int error);
virtual bool write();
#endif
};
diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc
index 4c26acd2cc1..0480a8fa59f 100644
--- a/sql/log_event_client.cc
+++ b/sql/log_event_client.cc
@@ -899,6 +899,16 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
fprintf(stderr, "\nError: Found Old DECIMAL (mysql-4.1 or earlier). "
"Not enough metadata to display the value.\n");
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:
print_event_info->flush_for_error();
fprintf(stderr,
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index b27f10c7d72..072c0a48269 100644
--- a/sql/mf_iocache_encr.cc
+++ b/sql/mf_iocache_encr.cc
@@ -71,6 +71,16 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
DBUG_RETURN(1);
}
info->seek_not_done= 0;
+ if (info->next_file_user)
+ {
+ IO_CACHE *c;
+ for (c= info->next_file_user;
+ c!= info;
+ c= c->next_file_user)
+ {
+ c->seek_not_done= 1;
+ }
+ }
}
do
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 2db08bf01e3..4c1f41463d5 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -217,15 +217,15 @@ public:
{
return to_string(to, 0, 0, 0);
}
- String *to_string_round(String *to, uint scale, my_decimal *round_buff) const
+ String *to_string_round(String *to, int scale, my_decimal *round_buff) const
{
(void) round_to(round_buff, scale, HALF_UP); // QQ: check result?
return round_buff->to_string(to);
}
- int round_to(my_decimal *to, uint scale, decimal_round_mode mode,
+ int round_to(my_decimal *to, int scale, decimal_round_mode mode,
int mask= E_DEC_FATAL_ERROR) const
{
- return check_result(mask, decimal_round(this, to, (int) scale, mode));
+ return check_result(mask, decimal_round(this, to, scale, mode));
}
int to_binary(uchar *bin, int prec, int scale,
uint mask= E_DEC_FATAL_ERROR) const;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 99ec7c1eb56..8417208d68f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1884,13 +1884,10 @@ extern "C" void unireg_abort(int exit_code)
WSREP_INFO("Some threads may fail to exit.");
}
- if (WSREP_ON)
+ if (WSREP_ON && wsrep_inited)
{
- /* In bootstrap mode we deinitialize wsrep here. */
- if (opt_bootstrap || wsrep_recovery)
- {
- if (wsrep_inited) wsrep_deinit(true);
- }
+ wsrep_deinit(true);
+ wsrep_deinit_server();
}
#endif // WITH_WSREP
@@ -6950,8 +6947,8 @@ show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff,
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
-static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
+static int show_default_keycache(THD *thd, SHOW_VAR *var, void *buff,
+ system_status_var *, enum_var_type)
{
struct st_data {
KEY_CACHE_STATISTICS stats;
@@ -6984,7 +6981,7 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
v->name= 0;
- DBUG_ASSERT((char*)(v+1) <= buff + SHOW_VAR_FUNC_BUFF_SIZE);
+ DBUG_ASSERT((char*)(v+1) <= static_cast<char*>(buff) + SHOW_VAR_FUNC_BUFF_SIZE);
#undef set_one_keycache_var
@@ -7008,8 +7005,8 @@ static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff,
#ifndef DBUG_OFF
-static int debug_status_func(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
+static int debug_status_func(THD *thd, SHOW_VAR *var, void *buff,
+ system_status_var *, enum_var_type)
{
#define add_var(X,Y,Z) \
v->name= X; \
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c674730d230..c13563f9263 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1872,6 +1872,9 @@ SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
next_key_part=arg.next_key_part;
max_part_no= arg.max_part_no;
use_count=1; elements=1;
+ next= 0;
+ if (next_key_part)
+ ++next_key_part->use_count;
}
@@ -9616,9 +9619,15 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
}
bool no_imerge_from_ranges= FALSE;
+ SEL_TREE *rt1= tree1;
+ SEL_TREE *rt2= tree2;
/* Build the range part of the tree for the formula (1) */
if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
{
+ if (no_merges1)
+ rt1= new SEL_TREE(tree1, TRUE, param);
+ if (no_merges2)
+ rt2= new SEL_TREE(tree2, TRUE, param);
bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
no_imerge_from_ranges= must_be_ored;
@@ -9676,12 +9685,6 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges)
{
/* Build the imerge part of the tree for the formula (1) */
- SEL_TREE *rt1= tree1;
- SEL_TREE *rt2= tree2;
- if (no_merges1)
- rt1= new SEL_TREE(tree1, TRUE, param);
- if (no_merges2)
- rt2= new SEL_TREE(tree2, TRUE, param);
if (!rt1 || !rt2 ||
result->merges.push_back(imerge_from_ranges) ||
imerge_from_ranges->or_sel_tree(param, rt1) ||
@@ -10346,10 +10349,11 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
if (!tmp->next_key_part)
{
+ SEL_ARG *key2_next= key2->next;
if (key2->use_count)
{
SEL_ARG *key2_cpy= new SEL_ARG(*key2);
- if (key2_cpy)
+ if (!key2_cpy)
return 0;
key2= key2_cpy;
}
@@ -10370,7 +10374,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
Move on to next range in key2
*/
key2->increment_use_count(-1); // Free not used tree
- key2=key2->next;
+ key2=key2_next;
continue;
}
else
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 8ae3ce5c995..b7f5ffd02d1 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1,5 +1,5 @@
/*
- 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
@@ -2681,16 +2681,11 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
do
{
uint key= keyuse->key;
- KEY *keyinfo;
key_part_map bound_parts= 0;
- bool is_excluded_key= keyuse->is_for_hash_join();
- if (!is_excluded_key)
- {
- keyinfo= table->key_info + key;
- is_excluded_key= !MY_TEST(keyinfo->flags & HA_NOSAME);
- }
- if (!is_excluded_key)
+ if (!keyuse->is_for_hash_join() &&
+ (table->key_info[key].flags & HA_NOSAME))
{
+ KEY *keyinfo= table->key_info + key;
do /* For all equalities on all key parts */
{
/*
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 0a3c30a176d..af2d9ddc2e7 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -399,20 +399,28 @@ int opt_sum_query(THD *thd,
break;
}
longlong info_limit= 1;
- table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
- if (likely(!(error= table->file->ha_index_init((uint) ref.key, 1))))
- error= (is_max ?
- get_index_max_value(table, &ref, range_fl) :
- get_index_min_value(table, &ref, item_field, range_fl,
- prefix_len));
+ error= 0;
+ table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
+ if (!table->const_table)
+ {
+ if (likely(!(error= table->file->ha_index_init((uint) ref.key,
+ 1))))
+ error= (is_max ?
+ get_index_max_value(table, &ref, range_fl) :
+ get_index_min_value(table, &ref, item_field, range_fl,
+ prefix_len));
+ }
/* Verify that the read tuple indeed matches the search key */
if (!error &&
reckey_in_range(is_max, &ref, item_field->field,
conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND;
- table->file->ha_end_keyread();
- table->file->ha_index_end();
+ if (!table->const_table)
+ {
+ table->file->ha_end_keyread();
+ table->file->ha_index_end();
+ }
table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL);
if (error)
{
diff --git a/sql/protocol.cc b/sql/protocol.cc
index d5e6a7b92bf..65443cafa65 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2008, 2012, 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
@@ -57,7 +57,8 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
packet->realloc(packet_length+9+length))
return 1;
uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
- memcpy(to,from,length);
+ if (length)
+ memcpy(to,from,length);
packet->length((uint) (to+length-(uchar*) packet->ptr()));
return 0;
}
@@ -730,7 +731,8 @@ void net_send_progress_packet(THD *thd)
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
{
to=net_store_length_fast(to,length);
- memcpy(to,from,length);
+ if (length)
+ memcpy(to,from,length);
return to+length;
}
diff --git a/sql/select_handler.cc b/sql/select_handler.cc
index 9a2f6398a86..795ed8eb641 100644
--- a/sql/select_handler.cc
+++ b/sql/select_handler.cc
@@ -21,10 +21,10 @@
/**
- The methods of the Pushdown_select class.
+ The methods of the select_handler class.
The objects of this class are used for pushdown of the select queries
- into engines. The main method of the class is Pushdown_select::execute()
+ into engines. The main method of the class is select_handler::execute()
that initiates execution of a select query by a foreign engine, receives the
rows of the result set, put it in a buffer of a temporary table and send
them from the buffer directly into output.
@@ -36,51 +36,55 @@
*/
-Pushdown_select::Pushdown_select(SELECT_LEX *sel, select_handler *h)
- : select(sel), handler(h)
-{
- is_analyze= handler->thd->lex->analyze_stmt;
-}
+select_handler::select_handler(THD *thd_arg, handlerton *ht_arg)
+ : thd(thd_arg), ht(ht_arg), table(NULL),
+ is_analyze(thd_arg->lex->analyze_stmt)
+{}
-Pushdown_select::~Pushdown_select()
+select_handler::~select_handler()
{
- if (handler->table)
- free_tmp_table(handler->thd, handler->table);
- delete handler;
- select->select_h= NULL;
+ if (table)
+ free_tmp_table(thd, table);
}
-bool Pushdown_select::init()
+TABLE *select_handler::create_tmp_table(THD *thd, SELECT_LEX *select)
{
+ DBUG_ENTER("select_handler::create_tmp_table");
List<Item> types;
TMP_TABLE_PARAM tmp_table_param;
- THD *thd= handler->thd;
- DBUG_ENTER("Pushdown_select::init");
if (select->master_unit()->join_union_item_types(thd, types, 1))
- DBUG_RETURN(true);
+ DBUG_RETURN(NULL);
tmp_table_param.init();
tmp_table_param.field_count= types.elements;
- handler->table= create_tmp_table(thd, &tmp_table_param, types,
+ TABLE *table= ::create_tmp_table(thd, &tmp_table_param, types,
(ORDER *) 0, false, 0,
TMP_TABLE_ALL_COLUMNS, 1,
&empty_clex_str, true, false);
- if (!handler->table)
- DBUG_RETURN(true);
- if (handler->table->fill_item_list(&result_columns))
+ DBUG_RETURN(table);
+}
+
+
+bool select_handler::prepare()
+{
+ DBUG_ENTER("select_handler::prepare");
+ /*
+ Some engines (e.g. XPand) initialize "table" on their own.
+ So we need to create a temporary table only if "table" is NULL.
+ */
+ if (!table && !(table= create_tmp_table(thd, select)))
DBUG_RETURN(true);
- DBUG_RETURN(false);
+ DBUG_RETURN(table->fill_item_list(&result_columns));
}
-bool Pushdown_select::send_result_set_metadata()
+bool select_handler::send_result_set_metadata()
{
- DBUG_ENTER("Pushdown_select::send_result_set_metadata");
+ DBUG_ENTER("select_handler::send_result_set_metadata");
#ifdef WITH_WSREP
- THD *thd= handler->thd;
if (WSREP(thd) && thd->wsrep_retry_query)
{
WSREP_DEBUG("skipping select metadata");
@@ -96,7 +100,7 @@ bool Pushdown_select::send_result_set_metadata()
}
-bool Pushdown_select::send_data()
+bool select_handler::send_data()
{
DBUG_ENTER("Pushdown_select::send_data");
@@ -107,9 +111,9 @@ bool Pushdown_select::send_data()
}
-bool Pushdown_select::send_eof()
+bool select_handler::send_eof()
{
- DBUG_ENTER("Pushdown_select::send_eof");
+ DBUG_ENTER("select_handler::send_eof");
if (select->join->result->send_eof())
DBUG_RETURN(true);
@@ -117,30 +121,29 @@ bool Pushdown_select::send_eof()
}
-int Pushdown_select::execute()
+int select_handler::execute()
{
int err;
- THD *thd= handler->thd;
- DBUG_ENTER("Pushdown_select::execute");
+ DBUG_ENTER("select_handler::execute");
- if ((err= handler->init_scan()))
+ if ((err= init_scan()))
goto error;
if (is_analyze)
{
- handler->end_scan();
+ end_scan();
DBUG_RETURN(0);
}
if (send_result_set_metadata())
DBUG_RETURN(-1);
- while (!(err= handler->next_row()))
+ while (!(err= next_row()))
{
if (thd->check_killed() || send_data())
{
- handler->end_scan();
+ end_scan();
DBUG_RETURN(-1);
}
}
@@ -148,7 +151,7 @@ int Pushdown_select::execute()
if (err != 0 && err != HA_ERR_END_OF_FILE)
goto error;
- if ((err= handler->end_scan()))
+ if ((err= end_scan()))
goto error_2;
if (send_eof())
@@ -157,9 +160,9 @@ int Pushdown_select::execute()
DBUG_RETURN(0);
error:
- handler->end_scan();
+ end_scan();
error_2:
- handler->print_error(err, MYF(0));
+ print_error(err, MYF(0));
DBUG_RETURN(-1); // Error not sent to client
}
diff --git a/sql/select_handler.h b/sql/select_handler.h
index e2ad13b7cdf..5cc63231641 100644
--- a/sql/select_handler.h
+++ b/sql/select_handler.h
@@ -41,12 +41,24 @@ class select_handler
The table is actually never filled. Only its record buffer is used.
*/
TABLE *table;
+ List<Item> result_columns;
- select_handler(THD *thd_arg, handlerton *ht_arg)
- : thd(thd_arg), ht(ht_arg), table(0) {}
+ bool is_analyze;
- virtual ~select_handler() {}
+ bool send_result_set_metadata();
+ bool send_data();
+ select_handler(THD *thd_arg, handlerton *ht_arg);
+
+ virtual ~select_handler();
+
+ int execute();
+
+ virtual bool prepare();
+
+ static TABLE *create_tmp_table(THD *thd, SELECT_LEX *sel);
+
+protected:
/*
Functions to scan the select result set.
All these returns 0 if ok, error code in case of error.
@@ -67,6 +79,8 @@ class select_handler
/* Report errors */
virtual void print_error(int error, myf errflag);
+
+ bool send_eof();
};
#endif /* SELECT_HANDLER_INCLUDED */
diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc
index 1e5e356a5ba..de82d8be90c 100644
--- a/sql/session_tracker.cc
+++ b/sql/session_tracker.cc
@@ -445,8 +445,11 @@ bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
show.name= svar->name.str;
show.value= (char *) svar;
+ mysql_mutex_lock(&LOCK_global_system_variables);
const char *value= get_one_variable(thd, &show, OPT_SESSION, SHOW_SYS, NULL,
&charset, val_buf, &val_length);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+
if (is_plugin)
mysql_mutex_unlock(&LOCK_plugin);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 38c8d1f1775..fe98d98fbd4 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1084,7 +1084,6 @@ static void store_var(Field *field, sys_var *var, enum_var_type scope,
int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
{
char name_buffer[NAME_CHAR_LEN];
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
bool res= 1;
CHARSET_INFO *scs= system_charset_info;
StringBuffer<STRING_BUFFER_USUAL_SIZE> strbuf(scs);
@@ -1095,7 +1094,6 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_ASSERT(tables->table->in_use == thd);
cond= make_cond_for_info_schema(thd, cond, tables);
- thd->count_cuted_fields= CHECK_FIELD_WARN;
mysql_prlock_rdlock(&LOCK_system_variables_hash);
for (uint i= 0; i < system_variable_hash.records; i++)
@@ -1269,7 +1267,6 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
res= 0;
end:
mysql_prlock_unlock(&LOCK_system_variables_hash);
- thd->count_cuted_fields= save_count_cuted_fields;
return res;
}
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 63c3ee30444..2e08892166d 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -1800,9 +1800,10 @@ ER_WRONG_AUTO_KEY 42000 S1009
slo "Môžete maÅ¥ iba jedno AUTO pole a to musí byÅ¥ definované ako kľúÄ"
spa "Puede ser solamente un campo automatico y este debe ser definido como una clave"
swe "Det får finnas endast ett AUTO_INCREMENT-fält och detta måste vara en nyckel"
- ukr "Ðевірне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ–; Може бути лише один автоматичний Ñтовбець, що повинен бути визначений Ñк ключ"
+ ukr "Хибне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ–; Може бути лише один автоматичний Ñтовбець, що повинен бути визначений Ñк ключ"
ER_BINLOG_CANT_DELETE_GTID_DOMAIN
eng "Could not delete gtid domain. Reason: %s."
+ ukr "Ðе можу видалити домен gtid. Причина: %s."
ER_NORMAL_SHUTDOWN
cze "%s (%s): normální ukonÄení"
dan "%s (%s): Normal nedlukning"
@@ -2203,6 +2204,7 @@ ER_INSERT_INFO
ER_UPDATE_TABLE_USED
eng "Table '%-.192s' is specified twice, both as a target for '%s' and as a separate source for data"
swe "Table '%-.192s' är använd två gånger. Både för '%s' och för att hämta data"
+ ukr "Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ '%-.192s' вказуєтьÑÑ Ð´Ð²Ñ–Ñ‡Ñ–, Ñк цільова Ð´Ð»Ñ '%s', так Ñ– Ñк окреме джерело даних"
ER_NO_SUCH_THREAD
cze "Neznámá identifikace threadu: %lu"
dan "Ukendt tråd id: %lu"
@@ -2824,6 +2826,7 @@ ER_WRONG_OUTER_JOIN 42000
ER_NULL_COLUMN_IN_INDEX 42000
eng "Table handler doesn't support NULL in given index. Please change column '%-.192s' to be NOT NULL or use another handler"
swe "Tabell hanteraren kan inte indexera NULL kolumner för den givna index typen. Ändra '%-.192s' till NOT NULL eller använd en annan hanterare"
+ ukr "Вказівник таблиці не підтримує NULL у зазначенному індекÑÑ–. Будь лаÑка, зменіть Ñтовпчик '%-.192s' на NOT NULL або викориÑтайте інший вказівник таблиці."
ER_CANT_FIND_UDF
cze "Nemohu naÄíst funkci '%-.192s'"
dan "Kan ikke læse funktionen '%-.192s'"
@@ -4314,6 +4317,7 @@ ER_MASTER_INFO
jpn "'master info '%.*s''構造体ã®åˆæœŸåŒ–ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚MariaDBエラーログã§ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’確èªã—ã¦ãã ã•ã„。"
serbian "Nisam mogao da inicijalizujem informacionu strukturu glavnog servera, proverite da li imam privilegije potrebne za pristup file-u 'master.info' '%.*s'"
swe "Kunde inte initialisera replikationsstrukturerna för '%.*s'. See MariaDB fel fil för mera information"
+ ukr "Інформаційна Ñтруктура з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð³Ð¾Ð»Ð¾Ð²Ð½Ð¾Ð³Ð¾ Ñ– підлеглого (master.info) Ð´Ð»Ñ '%.*s' не може бути ініціалізована"
ER_SLAVE_THREAD
dan "Kunne ikke danne en slave-tråd; check systemressourcerne"
nla "Kon slave thread niet aanmaken, controleer systeem resources"
@@ -4478,6 +4482,7 @@ ER_UNION_TABLES_IN_DIFFERENT_DIR
serbian "Pogrešna definicija tabele; sve 'MERGE' tabele moraju biti u istoj bazi podataka"
spa "Incorrecta definición de la tabla; Todas las tablas MERGE deben estar en el mismo banco de datos"
swe "Felaktig tabelldefinition; alla tabeller i en MERGE-tabell måste vara i samma databas"
+ ukr "Хибне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ–; вÑÑ– MERGE-таблиці повинні належити до однієї бази ланних."
ER_LOCK_DEADLOCK 40001
nla "Deadlock gevonden tijdens lock-aanvraag poging; Probeer herstart van de transactie"
eng "Deadlock found when trying to get lock; try restarting transaction"
@@ -4491,6 +4496,7 @@ ER_LOCK_DEADLOCK 40001
serbian "Unakrsno zakljuÄavanje pronaÄ‘eno kada sam pokuÅ¡ao da dobijem pravo na zakljuÄavanje; Probajte da restartujete transakciju"
spa "Encontrado deadlock cuando tentando obtener el bloqueo; Tente recomenzar la transición"
swe "Fick 'DEADLOCK' vid låsförsök av block/rad. Försök att starta om transaktionen"
+ ukr "Взаємне Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾ під Ñ‡Ð°Ñ Ñпроби отримати блокуваннÑ; Ñпробуйте перезапуÑтити транзакцію."
ER_TABLE_CANT_HANDLE_FT
nla "Het gebruikte tabel type (%s) ondersteund geen FULLTEXT indexen"
eng "The storage engine %s doesn't support FULLTEXT indexes"
@@ -4517,6 +4523,7 @@ ER_CANNOT_ADD_FOREIGN
serbian "Ne mogu da dodam proveru spoljnog kljuÄa na `%s`"
spa "No puede adicionar clave extranjera constraint para `%s`"
swe "Kan inte lägga till 'FOREIGN KEY constraint' för `%s`'"
+ ukr "Ðе можу додати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ ключа Ha `%s`"
ER_NO_REFERENCED_ROW 23000
nla "Kan onderliggende rij niet toevoegen: foreign key beperking gefaald"
eng "Cannot add or update a child row: a foreign key constraint fails"
@@ -4531,6 +4538,7 @@ ER_NO_REFERENCED_ROW 23000
rus "Ðевозможно добавить или обновить дочернюю Ñтроку: проверка ограничений внешнего ключа не выполнÑетÑÑ"
spa "No puede adicionar una línea hijo: falla de clave extranjera constraint"
swe "FOREIGN KEY-konflikt: Kan inte skriva barn"
+ ukr "Ðе вдаєтьÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ або оновити дочірній Ñ€Ñдок: невдала перевірка Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ ключа"
ER_ROW_IS_REFERENCED 23000
eng "Cannot delete or update a parent row: a foreign key constraint fails"
fre "Impossible de supprimer un enregistrement père : une constrainte externe l'empèche"
@@ -5714,8 +5722,9 @@ ER_SP_RECURSION_LIMIT
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.192s"
ger "Rekursionsgrenze %d (durch Variable max_sp_recursion_depth gegeben) wurde für Routine %.192s überschritten"
ER_SP_PROC_TABLE_CORRUPT
- eng "Failed to load routine %-.192s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
- ger "Routine %-.192s konnte nicht geladen werden. Die Tabelle mysql.proc fehlt, ist beschädigt, oder enthält fehlerhaften Daten (interner Code: %d)"
+ eng "Failed to load routine %-.192s (internal code %d). For more details, run SHOW WARNINGS"
+ ger "Routine %-.192s (interner Code %d) konnte nicht geladen werden. Weitere Einzelheiten erhalten Sie, wenn Sie SHOW WARNINGS ausführen"
+ ukr "Ðевдала Ñпроба завантажити процедуру %-.192s (внутрішний код %d). Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— інформації викориÑтовуйте SHOW WARNINGS"
ER_SP_WRONG_NAME 42000
eng "Incorrect routine name '%-.192s'"
ger "Ungültiger Routinenname '%-.192s'"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 49c8229c277..9e5b5bee0f2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1211,6 +1211,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
Query_arena execute_arena(&execute_mem_root, STMT_INITIALIZED_FOR_SP),
backup_arena;
query_id_t old_query_id;
+ CSET_STRING old_query;
TABLE *old_derived_tables;
TABLE *old_rec_tables;
LEX *old_lex;
@@ -1291,6 +1292,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
be able properly do close_thread_tables() in instructions.
*/
old_query_id= thd->query_id;
+ old_query= thd->query_string;
old_derived_tables= thd->derived_tables;
thd->derived_tables= 0;
old_rec_tables= thd->rec_tables;
@@ -1567,6 +1569,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
old_change_list.move_elements_to(thd);
thd->lex= old_lex;
thd->set_query_id(old_query_id);
+ thd->set_query_inner(old_query);
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
thd->rec_tables= old_rec_tables;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 161ffc66641..2c96e0e9ff2 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -304,8 +304,9 @@ ulong role_global_merges= 0, role_db_merges= 0, role_table_merges= 0,
static void update_hostname(acl_host_and_ip *host, const char *hostname);
static bool show_proxy_grants (THD *, const char *, const char *,
char *, size_t);
-static bool show_role_grants(THD *, const char *, const char *,
+static bool show_role_grants(THD *, const char *,
ACL_USER_BASE *, char *, size_t);
+static bool show_default_role(THD *, ACL_USER *, char *, size_t);
static bool show_global_privileges(THD *, ACL_USER_BASE *,
bool, char *, size_t);
static bool show_database_privileges(THD *, const char *, const char *,
@@ -9000,7 +9001,7 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role)
{
char buff[1024];
- if (show_role_grants(thd, role->user.str, "", role, buff, sizeof(buff)))
+ if (show_role_grants(thd, "", role, buff, sizeof(buff)))
return TRUE;
if (show_global_privileges(thd, role, TRUE, buff, sizeof(buff)))
@@ -9245,7 +9246,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
}
/* Show granted roles to acl_user */
- if (show_role_grants(thd, username, hostname, acl_user, buff, sizeof(buff)))
+ if (show_role_grants(thd, hostname, acl_user, buff, sizeof(buff)))
goto end;
/* Add first global access grants */
@@ -9302,6 +9303,14 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
}
}
+ if (username)
+ {
+ /* Show default role to acl_user */
+ if (show_default_role(thd, acl_user, buff, sizeof(buff)))
+ goto end;
+ }
+
+
error= 0;
end:
mysql_mutex_unlock(&acl_cache->lock);
@@ -9328,15 +9337,44 @@ static ROLE_GRANT_PAIR *find_role_grant_pair(const LEX_CSTRING *u,
my_hash_search(&acl_roles_mappings, (uchar*)pair_key.ptr(), key_length);
}
-static bool show_role_grants(THD *thd, const char *username,
- const char *hostname, ACL_USER_BASE *acl_entry,
+static bool show_default_role(THD *thd, ACL_USER *acl_entry,
+ char *buff, size_t buffsize)
+{
+ Protocol *protocol= thd->protocol;
+ LEX_CSTRING def_rolename= acl_entry->default_rolename;
+
+ if (def_rolename.length)
+ {
+ String def_str(buff, buffsize, system_charset_info);
+ def_str.length(0);
+ def_str.append(STRING_WITH_LEN("SET DEFAULT ROLE "));
+ def_str.append(&def_rolename);
+ def_str.append(" FOR '");
+ def_str.append(&acl_entry->user);
+ DBUG_ASSERT(!(acl_entry->flags & IS_ROLE));
+ def_str.append(STRING_WITH_LEN("'@'"));
+ def_str.append(acl_entry->host.hostname, acl_entry->hostname_length,
+ system_charset_info);
+ def_str.append('\'');
+ protocol->prepare_for_resend();
+ protocol->store(def_str.ptr(),def_str.length(),def_str.charset());
+ if (protocol->write())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool show_role_grants(THD *thd, const char *hostname,
+ ACL_USER_BASE *acl_entry,
char *buff, size_t buffsize)
{
uint counter;
Protocol *protocol= thd->protocol;
LEX_CSTRING host= {const_cast<char*>(hostname), strlen(hostname)};
- String grant(buff,sizeof(buff),system_charset_info);
+ String grant(buff, buffsize, system_charset_info);
for (counter= 0; counter < acl_entry->role_grants.elements; counter++)
{
grant.length(0);
@@ -9377,7 +9415,7 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
privilege_t want_access(NO_ACL);
Protocol *protocol= thd->protocol;
- String global(buff,sizeof(buff),system_charset_info);
+ String global(buff, buffsize, system_charset_info);
global.length(0);
global.append(STRING_WITH_LEN("GRANT "));
@@ -9471,7 +9509,7 @@ static bool show_database_privileges(THD *thd, const char *username,
want_access=acl_db->initial_access;
if (want_access)
{
- String db(buff,sizeof(buff),system_charset_info);
+ String db(buff, buffsize, system_charset_info);
db.length(0);
db.append(STRING_WITH_LEN("GRANT "));
@@ -14679,3 +14717,40 @@ maria_declare_plugin(mysql_password)
MariaDB_PLUGIN_MATURITY_STABLE /* Maturity */
}
maria_declare_plugin_end;
+
+
+/*
+ Exporting functions that allow plugins to do server-style
+ host/user matching. Used in server_audit2 plugin.
+*/
+extern "C" int maria_compare_hostname(
+ const char *wild_host, long wild_ip, long ip_mask,
+ const char *host, const char *ip)
+{
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ acl_host_and_ip h;
+ h.hostname= (char *) wild_host;
+ h.ip= wild_ip;
+ h.ip_mask= ip_mask;
+
+ return compare_hostname(&h, host, ip);
+#else
+ return 0;
+#endif
+}
+
+
+extern "C" void maria_update_hostname(
+ const char **wild_host, long *wild_ip, long *ip_mask,
+ const char *host)
+{
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ acl_host_and_ip h;
+ update_hostname(&h, host);
+ *wild_host= h.hostname;
+ *wild_ip= h.ip;
+ *ip_mask= h.ip_mask;
+#endif
+}
+
+
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 6a313616025..dec5bd91f36 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1316,7 +1316,12 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
table->s->tdc->flush(thd, true);
/* extra() call must come only after all instances above are closed */
if (function != HA_EXTRA_NOT_USED)
- DBUG_RETURN(table->file->extra(function));
+ {
+ int error= table->file->extra(function);
+ if (error)
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
DBUG_RETURN(FALSE);
}
@@ -1777,7 +1782,14 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
}
if (is_locked_view(thd, table_list))
+ {
+ if (table_list->sequence)
+ {
+ my_error(ER_NOT_SEQUENCE, MYF(0), table_list->db.str, table_list->alias.str);
+ DBUG_RETURN(true);
+ }
DBUG_RETURN(FALSE); // VIEW
+ }
/*
No table in the locked tables list. In case of explicit LOCK TABLES
@@ -1906,7 +1918,12 @@ retry_share:
DBUG_RETURN(FALSE);
}
+#ifdef WITH_WSREP
+ if (!((flags & MYSQL_OPEN_IGNORE_FLUSH) ||
+ (thd->wsrep_applier)))
+#else
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
+#endif
{
if (share->tdc->flushed)
{
@@ -3900,7 +3917,8 @@ static bool upgrade_lock_if_not_exists(THD *thd,
{
DEBUG_SYNC(thd,"create_table_before_check_if_exists");
if (!create_info.or_replace() &&
- ha_table_exists(thd, &create_table->db, &create_table->table_name))
+ ha_table_exists(thd, &create_table->db, &create_table->table_name,
+ &create_table->db_type))
{
if (create_info.if_not_exists())
{
@@ -3948,7 +3966,8 @@ static bool upgrade_lock_if_not_exists(THD *thd,
Note that for CREATE TABLE IF EXISTS we only generate a warning
but still return TRUE (to abort the calling open_table() function).
On must check THD->is_error() if one wants to distinguish between warning
- and error.
+ and error. If table existed, tables_start->db_type is set to the handlerton
+ for the found table.
*/
bool
@@ -8734,14 +8753,17 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
goto err;
field->set_has_explicit_value();
}
- /* Update virtual fields */
- thd->abort_on_warning= FALSE;
- if (table->versioned())
- table->vers_update_fields();
- if (table->vfield &&
- table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
- goto err;
- thd->abort_on_warning= abort_on_warning_saved;
+ /* Update virtual fields if there wasn't any errors */
+ if (!thd->is_error())
+ {
+ thd->abort_on_warning= FALSE;
+ if (table->versioned())
+ table->vers_update_fields();
+ if (table->vfield &&
+ table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
+ goto err;
+ thd->abort_on_warning= abort_on_warning_saved;
+ }
DBUG_RETURN(thd->is_error());
err:
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index e32344115da..3db7ebc7997 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1298,6 +1298,7 @@ void THD::init()
first_successful_insert_id_in_prev_stmt_for_binlog= 0;
first_successful_insert_id_in_cur_stmt= 0;
current_backup_stage= BACKUP_FINISHED;
+ backup_commit_lock= 0;
#ifdef WITH_WSREP
wsrep_last_query_id= 0;
wsrep_xid.null();
@@ -2588,7 +2589,7 @@ void THD::give_protection_error()
my_error(ER_BACKUP_LOCK_IS_ACTIVE, MYF(0));
else
{
- DBUG_ASSERT(global_read_lock.is_acquired());
+ DBUG_ASSERT(global_read_lock.is_acquired() || mdl_backup_lock);
my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
}
}
@@ -6552,8 +6553,8 @@ exit:;
/**
Check if we should log a table DDL to the binlog
- @@return true yes
- @@return false no
+ @retval true yes
+ @retval false no
*/
bool THD::binlog_table_should_be_logged(const LEX_CSTRING *db)
@@ -7442,14 +7443,14 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
*/
if (binlog_should_compress(query_len))
{
- Query_compressed_log_event qinfo(this, query_arg, query_len, is_trans, direct,
- suppress_use, errcode);
+ Query_compressed_log_event qinfo(this, query_arg, query_len, is_trans,
+ direct, suppress_use, errcode);
error= mysql_bin_log.write(&qinfo);
}
else
{
Query_log_event qinfo(this, query_arg, query_len, is_trans, direct,
- suppress_use, errcode);
+ suppress_use, errcode);
error= mysql_bin_log.write(&qinfo);
}
/*
@@ -7467,6 +7468,38 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
DBUG_RETURN(0);
}
+
+/**
+ Binlog current query as a statement, ignoring the binlog filter setting.
+
+ The filter is in decide_logging_format() to mark queries to not be stored
+ in the binary log, for example by a shared distributed engine like S3.
+ This function resets the filter to ensure the the query is logged if
+ the binlog is active.
+
+ Note that 'direct' is set to false, which means that the query will
+ not be directly written to the binary log but instead to the cache.
+
+ @retval false ok
+ @retval true error
+*/
+
+
+bool THD::binlog_current_query_unfiltered()
+{
+ if (!mysql_bin_log.is_open())
+ return 0;
+
+ reset_binlog_local_stmt_filter();
+ clear_binlog_local_stmt_filter();
+ return binlog_query(THD::STMT_QUERY_TYPE, query(), query_length(),
+ /* is_trans */ FALSE,
+ /* direct */ FALSE,
+ /* suppress_use */ FALSE,
+ /* Error */ 0) > 0;
+}
+
+
void
THD::wait_for_wakeup_ready()
{
@@ -7642,16 +7675,33 @@ wait_for_commit::register_wait_for_prior_commit(wait_for_commit *waitee)
}
-/*
- Wait for commit of another transaction to complete, as already registered
+/**
+ Waits for commit of another transaction to complete, as already registered
with register_wait_for_prior_commit(). If the commit already completed,
returns immediately.
+
+ If thd->backup_commit_lock is set, release it while waiting for other threads
*/
+
int
wait_for_commit::wait_for_prior_commit2(THD *thd)
{
PSI_stage_info old_stage;
wait_for_commit *loc_waitee;
+ bool backup_lock_released= 0;
+
+ /*
+ Release MDL_BACKUP_COMMIT LOCK while waiting for other threads to commit
+ This is needed to avoid deadlock between the other threads (which not
+ yet have the MDL_BACKUP_COMMIT_LOCK) and any threads using
+ BACKUP LOCK BLOCK_COMMIT.
+ */
+ if (thd->backup_commit_lock && thd->backup_commit_lock->ticket)
+ {
+ backup_lock_released= 1;
+ thd->mdl_context.release_lock(thd->backup_commit_lock->ticket);
+ thd->backup_commit_lock->ticket= 0;
+ }
mysql_mutex_lock(&LOCK_wait_commit);
DEBUG_SYNC(thd, "wait_for_prior_commit_waiting");
@@ -7701,10 +7751,16 @@ wait_for_commit::wait_for_prior_commit2(THD *thd)
use within enter_cond/exit_cond.
*/
DEBUG_SYNC(thd, "wait_for_prior_commit_killed");
+ if (backup_lock_released)
+ thd->mdl_context.acquire_lock(thd->backup_commit_lock,
+ thd->variables.lock_wait_timeout);
return wakeup_error;
end:
thd->EXIT_COND(&old_stage);
+ if (backup_lock_released)
+ thd->mdl_context.acquire_lock(thd->backup_commit_lock,
+ thd->variables.lock_wait_timeout);
return wakeup_error;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index b0f68aa8fab..f6b772ef439 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -284,8 +284,9 @@ class Key_part_spec :public Sql_alloc {
public:
LEX_CSTRING field_name;
uint length;
- Key_part_spec(const LEX_CSTRING *name, uint len)
- : field_name(*name), length(len)
+ bool generated;
+ Key_part_spec(const LEX_CSTRING *name, uint len, bool gen= false)
+ : field_name(*name), length(len), generated(gen)
{}
bool operator==(const Key_part_spec& other) const;
/**
@@ -2311,7 +2312,10 @@ public:
rpl_io_thread_info *rpl_io_info;
rpl_sql_thread_info *rpl_sql_info;
} system_thread_info;
+ /* Used for BACKUP LOCK */
MDL_ticket *mdl_backup_ticket, *mdl_backup_lock;
+ /* Used to register that thread has a MDL_BACKUP_WAIT_COMMIT lock */
+ MDL_request *backup_commit_lock;
void reset_for_next_command(bool do_clear_errors= 1);
/*
@@ -2758,10 +2762,14 @@ public:
{
free_root(&mem_root,MYF(0));
}
- my_bool is_active()
+ bool is_active()
{
return (all.ha_list != NULL);
}
+ bool is_empty()
+ {
+ return all.is_empty() && stmt.is_empty();
+ }
st_transactions()
{
bzero((char*)this, sizeof(*this));
@@ -3483,6 +3491,7 @@ public:
char const *query, ulong query_len, bool is_trans,
bool direct, bool suppress_use,
int errcode);
+ bool binlog_current_query_unfiltered();
#endif
inline void
@@ -3765,10 +3774,17 @@ public:
/* Commit both statement and full transaction */
int commit_whole_transaction_and_close_tables();
void give_protection_error();
+ /*
+ Give an error if any of the following is true for this connection
+ - BACKUP STAGE is active
+ - FLUSH TABLE WITH READ LOCK is active
+ - BACKUP LOCK table_name is active
+ */
inline bool has_read_only_protection()
{
if (current_backup_stage == BACKUP_FINISHED &&
- !global_read_lock.is_acquired())
+ !global_read_lock.is_acquired() &&
+ !mdl_backup_lock)
return FALSE;
give_protection_error();
return TRUE;
@@ -6873,11 +6889,11 @@ public:
/**
SP Bulk execution safe
*/
-#define CF_SP_BULK_SAFE (1U << 20)
+#define CF_PS_ARRAY_BINDING_SAFE (1U << 20)
/**
SP Bulk execution optimized
*/
-#define CF_SP_BULK_OPTIMIZED (1U << 21)
+#define CF_PS_ARRAY_BINDING_OPTIMIZED (1U << 21)
/**
If command creates or drops a table
*/
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 17f8995239c..35aa306c88c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -248,6 +248,7 @@ int update_portion_of_time(THD *thd, TABLE *table,
uint dst_fieldno= lcond ? table->s->period.end_fieldno
: table->s->period.start_fieldno;
+ table->file->store_auto_increment();
store_record(table, record[1]);
if (likely(!res))
res= src->save_in_field(table->field[dst_fieldno], true);
@@ -262,6 +263,8 @@ int update_portion_of_time(THD *thd, TABLE *table,
res= table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, true);
restore_record(table, record[1]);
+ if (res)
+ table->file->restore_auto_increment();
if (likely(!res) && lcond && rcond)
res= table->period_make_insert(period_conds.end.item,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 4ad4c478937..7833059438e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -724,6 +724,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
Item *unused_conds= 0;
DBUG_ENTER("mysql_insert");
+ bzero((char*) &info,sizeof(info));
create_explain_query(thd->lex, thd->mem_root);
/*
Upgrade lock type if the requested lock is incompatible with
@@ -764,16 +765,28 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
value_count= values->elements;
- if (mysql_prepare_insert(thd, table_list, table, fields, values,
- update_fields, update_values, duplic,
- &unused_conds, FALSE))
+ if ((res= mysql_prepare_insert(thd, table_list, fields, values,
+ update_fields, update_values, duplic,
+ &unused_conds, FALSE)))
+ {
+ retval= thd->is_error();
+ if (res < 0)
+ {
+ /*
+ Insert should be ignored but we have to log the query in statement
+ format in the binary log
+ */
+ if (thd->binlog_current_query_unfiltered())
+ retval= 1;
+ }
goto abort;
+ }
+ /* mysql_prepare_insert sets table_list->table if it was not set */
+ table= table_list->table;
/* Prepares LEX::returing_list if it is not empty */
if (returning)
result->prepare(returning->item_list, NULL);
- /* mysql_prepare_insert sets table_list->table if it was not set */
- table= table_list->table;
context= &thd->lex->first_select_lex()->context;
/*
@@ -828,7 +841,6 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
/*
Fill in the given fields and dump it to the table file
*/
- bzero((char*) &info,sizeof(info));
info.ignore= ignore;
info.handle_duplicates=duplic;
info.update_fields= &update_fields;
@@ -1199,7 +1211,7 @@ values_loop_end:
such case the flag is ignored for constructing binlog event.
*/
DBUG_ASSERT(thd->killed != KILL_BAD_DATA || error > 0);
- if (was_insert_delayed && table_list->lock_type == TL_WRITE)
+ if (was_insert_delayed && table_list->lock_type == TL_WRITE)
{
/* Binlog INSERT DELAYED as INSERT without DELAYED. */
String log_query;
@@ -1534,9 +1546,6 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
mysql_prepare_insert()
thd Thread handler
table_list Global/local table list
- table Table to insert into
- (can be NULL if table should
- be taken from table_list->table)
where Where clause (for insert ... select)
select_insert TRUE if INSERT ... SELECT statement
@@ -1551,15 +1560,16 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
before releasing the table object.
RETURN VALUE
- FALSE OK
- TRUE error
+ 0 OK
+ >0 error
+ <0 insert should be ignored
*/
-bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
- TABLE *table, List<Item> &fields, List_item *values,
- List<Item> &update_fields, List<Item> &update_values,
- enum_duplicates duplic, COND **where,
- bool select_insert)
+int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
+ List<Item> &fields, List_item *values,
+ List<Item> &update_fields, List<Item> &update_values,
+ enum_duplicates duplic, COND **where,
+ bool select_insert)
{
SELECT_LEX *select_lex= thd->lex->first_select_lex();
Name_resolution_context *context= &select_lex->context;
@@ -1567,29 +1577,34 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
bool insert_into_view= (table_list->view != 0);
bool res= 0;
table_map map= 0;
+ TABLE *table;
DBUG_ENTER("mysql_prepare_insert");
- DBUG_PRINT("enter", ("table_list: %p table: %p view: %d",
- table_list, table,
- (int)insert_into_view));
+ DBUG_PRINT("enter", ("table_list: %p view: %d",
+ table_list, (int) insert_into_view));
/* INSERT should have a SELECT or VALUES clause */
DBUG_ASSERT (!select_insert || !values);
if (mysql_handle_derived(thd->lex, DT_INIT))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
if (duplic == DUP_UPDATE)
{
/* it should be allocated before Item::fix_fields() */
if (table_list->set_insert_values(thd->mem_root))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
}
+ table= table_list->table;
+
+ if (table->file->check_if_updates_are_ignored("INSERT"))
+ DBUG_RETURN(-1);
+
if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
/* Prepare the fields in the statement. */
if (values)
@@ -1632,9 +1647,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if (res)
DBUG_RETURN(res);
- if (!table)
- table= table_list->table;
-
if (check_duplic_insert_without_overlaps(thd, table, duplic) != 0)
DBUG_RETURN(true);
@@ -1642,7 +1654,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
{
// Additional memory may be required to create historical items.
if (table_list->set_insert_values(thd->mem_root))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
}
if (!select_insert)
@@ -1653,7 +1665,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
CHECK_DUP_ALLOW_DIFFERENT_ALIAS)))
{
update_non_unique_table_error(table_list, "INSERT", duplicate);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(1);
}
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
}
@@ -1663,7 +1675,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
*/
if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
prepare_for_positional_update(table, table_list);
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(0);
}
@@ -3703,12 +3715,14 @@ bool Delayed_insert::handle_inserts(void)
thd thread handler
RETURN
- FALSE OK
- TRUE Error
+ 0 OK
+ > 0 Error
+ < 0 Ok, ignore insert
*/
-bool mysql_insert_select_prepare(THD *thd, select_result *sel_res)
+int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
{
+ int res;
LEX *lex= thd->lex;
SELECT_LEX *select_lex= lex->first_select_lex();
DBUG_ENTER("mysql_insert_select_prepare");
@@ -3718,11 +3732,11 @@ bool mysql_insert_select_prepare(THD *thd, select_result *sel_res)
clause if table is VIEW
*/
- if (mysql_prepare_insert(thd, lex->query_tables,
- lex->query_tables->table, lex->field_list, 0,
- lex->update_list, lex->value_list, lex->duplicates,
- &select_lex->where, TRUE))
- DBUG_RETURN(TRUE);
+ if ((res= mysql_prepare_insert(thd, lex->query_tables, lex->field_list, 0,
+ lex->update_list, lex->value_list,
+ lex->duplicates,
+ &select_lex->where, TRUE)))
+ DBUG_RETURN(res);
/*
If sel_res is not empty, it means we have items in returing_list.
@@ -3763,7 +3777,7 @@ bool mysql_insert_select_prepare(THD *thd, select_result *sel_res)
while ((table= ti++) && insert_tables--)
ti.remove();
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(0);
}
@@ -3809,15 +3823,18 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
lex->current_select= lex->first_select_lex();
- res= setup_returning_fields(thd, table_list) ||
- setup_fields(thd, Ref_ptr_array(), values, MARK_COLUMNS_READ, 0, 0, 0) ||
- check_insert_fields(thd, table_list, *fields, values,
- !insert_into_view, 1, &map);
+ res= (setup_returning_fields(thd, table_list) ||
+ setup_fields(thd, Ref_ptr_array(), values, MARK_COLUMNS_READ, 0, 0,
+ 0) ||
+ check_insert_fields(thd, table_list, *fields, values,
+ !insert_into_view, 1, &map));
if (!res && fields->elements)
{
- Abort_on_warning_instant_set aws(thd, !info.ignore && thd->is_strict_mode());
- res= check_that_all_fields_are_given_values(thd, table_list->table, table_list);
+ Abort_on_warning_instant_set aws(thd,
+ !info.ignore && thd->is_strict_mode());
+ res= check_that_all_fields_are_given_values(thd, table_list->table,
+ table_list);
}
if (info.handle_duplicates == DUP_UPDATE && !res)
diff --git a/sql/sql_insert.h b/sql/sql_insert.h
index 14041976973..80666a81c50 100644
--- a/sql/sql_insert.h
+++ b/sql/sql_insert.h
@@ -23,11 +23,11 @@
typedef List<Item> List_item;
typedef struct st_copy_info COPY_INFO;
-bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
- List<Item> &fields, List_item *values,
- List<Item> &update_fields,
- List<Item> &update_values, enum_duplicates duplic,
- COND **where, bool select_insert);
+int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
+ List<Item> &fields, List_item *values,
+ List<Item> &update_fields,
+ List<Item> &update_values, enum_duplicates duplic,
+ COND **where, bool select_insert);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 592b53ceecf..61e3b89c9a3 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -3997,21 +3997,21 @@ bool LEX::can_not_use_merged()
}
}
-/*
- Detect that we need only table structure of derived table/view
+/**
+ Detect that we need only table structure of derived table/view.
- SYNOPSIS
- only_view_structure()
+ Also used by I_S tables (@see create_schema_table) to detect that
+ they need a full table structure and cannot optimize unused columns away
- RETURN
- TRUE yes, we need only structure
- FALSE no, we need data
+ @retval TRUE yes, we need only structure
+ @retval FALSE no, we need data
*/
bool LEX::only_view_structure()
{
switch (sql_command) {
case SQLCOM_SHOW_CREATE:
+ case SQLCOM_CHECKSUM:
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_FIELDS:
case SQLCOM_REVOKE_ALL:
@@ -4019,6 +4019,8 @@ bool LEX::only_view_structure()
case SQLCOM_GRANT:
case SQLCOM_CREATE_VIEW:
return TRUE;
+ case SQLCOM_CREATE_TABLE:
+ return create_info.like();
default:
return FALSE;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a07121b9a58..3e59ad3afc9 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1334,10 +1334,8 @@ public:
table_value_constr *tvc;
bool in_tvc;
- /* The interface employed to execute the select query by a foreign engine */
- select_handler *select_h;
/* The object used to organize execution of the query by a foreign engine */
- Pushdown_select *pushdown_select;
+ select_handler *pushdown_select;
/** System Versioning */
public:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 554c62f6538..0488b240bb2 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -98,6 +98,8 @@
#include "my_json_writer.h"
+#define PRIV_LOCK_TABLES (SELECT_ACL | LOCK_TABLES_ACL)
+
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
#ifdef WITH_ARIA_STORAGE_ENGINE
@@ -576,19 +578,21 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED |
- CF_UPDATES_DATA | CF_SP_BULK_SAFE;
+ CF_UPDATES_DATA |
+ CF_PS_ARRAY_BINDING_SAFE;
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED |
- CF_UPDATES_DATA | CF_SP_BULK_SAFE;
+ CF_UPDATES_DATA |
+ CF_PS_ARRAY_BINDING_SAFE;
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED |
CF_INSERTS_DATA |
- CF_SP_BULK_SAFE |
- CF_SP_BULK_OPTIMIZED;
+ CF_PS_ARRAY_BINDING_SAFE |
+ CF_PS_ARRAY_BINDING_OPTIMIZED;
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
@@ -598,7 +602,8 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED |
- CF_SP_BULK_SAFE | CF_DELETES_DATA;
+ CF_DELETES_DATA |
+ CF_PS_ARRAY_BINDING_SAFE;
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
@@ -608,8 +613,9 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
CF_CAN_BE_EXPLAINED |
- CF_INSERTS_DATA | CF_SP_BULK_SAFE |
- CF_SP_BULK_OPTIMIZED;
+ CF_INSERTS_DATA |
+ CF_PS_ARRAY_BINDING_SAFE |
+ CF_PS_ARRAY_BINDING_OPTIMIZED;
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS |
CF_OPTIMIZER_TRACE |
@@ -772,7 +778,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_ALTER_SERVER]= CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_SERVER]= CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_BACKUP]= CF_AUTO_COMMIT_TRANS;
- sql_command_flags[SQLCOM_BACKUP_LOCK]= 0;
+ sql_command_flags[SQLCOM_BACKUP_LOCK]= CF_AUTO_COMMIT_TRANS;
/*
The following statements can deal with temporary tables,
@@ -1090,7 +1096,6 @@ int bootstrap(MYSQL_FILE *file)
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
- thd->transaction->free();
thd->lex->restore_set_statement_var();
}
delete thd;
@@ -2825,6 +2830,36 @@ retry:
goto err;
}
}
+ /*
+ Check privileges of view tables here, after views were opened.
+ Either definer or invoker has to have PRIV_LOCK_TABLES to be able
+ to lock view and its tables. For mysqldump (that locks views
+ before dumping their structures) compatibility we allow locking
+ views that select from I_S or P_S tables, but downrade the lock
+ to TL_READ
+ */
+ if (table->belong_to_view &&
+ check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1))
+ {
+ if (table->grant.m_internal.m_schema_access)
+ table->lock_type= TL_READ;
+ else
+ {
+ bool error= true;
+ if (Security_context *sctx= table->security_ctx)
+ {
+ table->security_ctx= 0;
+ error= check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1);
+ table->security_ctx= sctx;
+ }
+ if (error)
+ {
+ my_error(ER_VIEW_INVALID, MYF(0), table->belong_to_view->view_db.str,
+ table->belong_to_view->view_name.str);
+ goto err;
+ }
+ }
+ }
}
if (lock_tables(thd, tables, counter, 0) ||
@@ -3683,6 +3718,7 @@ mysql_execute_command(THD *thd)
lex->sql_command != SQLCOM_BEGIN &&
lex->sql_command != SQLCOM_CALL &&
lex->sql_command != SQLCOM_EXECUTE &&
+ lex->sql_command != SQLCOM_EXECUTE_IMMEDIATE &&
!(sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS))
{
wsrep_start_trx_if_not_started(thd);
@@ -4255,6 +4291,11 @@ mysql_execute_command(THD *thd)
/* mysql_update return 2 if we need to switch to multi-update */
if (up_result != 2)
break;
+ if (thd->lex->period_conditions.is_set())
+ {
+ DBUG_ASSERT(0); // Should never happen
+ goto error;
+ }
}
/* fall through */
case SQLCOM_UPDATE_MULTI:
@@ -4569,6 +4610,14 @@ mysql_execute_command(THD *thd)
}
delete sel_result;
}
+ else if (res < 0)
+ {
+ /*
+ Insert should be ignored but we have to log the query in statement
+ format in the binary log
+ */
+ res= thd->binlog_current_query_unfiltered();
+ }
delete result;
if (save_protocol)
{
@@ -4924,6 +4973,13 @@ mysql_execute_command(THD *thd)
goto error;
}
+ /* Should not lock tables while BACKUP LOCK is active */
+ if (thd->mdl_backup_lock)
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ goto error;
+ }
+
/*
Here we have to pre-open temporary tables for LOCK TABLES.
@@ -5217,7 +5273,7 @@ mysql_execute_command(THD *thd)
if (first_table && lex->type & (REFRESH_READ_LOCK|REFRESH_FOR_EXPORT))
{
/* Check table-level privileges. */
- if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
+ if (check_table_access(thd, PRIV_LOCK_TABLES, all_tables,
FALSE, UINT_MAX, FALSE))
goto error;
@@ -6328,24 +6384,21 @@ drop_routine(THD *thd, LEX *lex)
! lex->spname->m_explicit_name)
{
/* DROP FUNCTION <non qualified name> */
- udf_func *udf = find_udf(lex->spname->m_name.str,
- lex->spname->m_name.length);
- if (udf)
- {
- if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 0))
- return 1;
-
- if (!mysql_drop_function(thd, &lex->spname->m_name))
- {
- my_ok(thd);
- return 0;
- }
- my_error(ER_SP_DROP_FAILED, MYF(0),
- "FUNCTION (UDF)", lex->spname->m_name.str);
+ enum drop_udf_result rc= mysql_drop_function(thd, &lex->spname->m_name);
+ switch (rc) {
+ case UDF_DEL_RESULT_DELETED:
+ my_ok(thd);
+ return 0;
+ case UDF_DEL_RESULT_ERROR:
return 1;
+ case UDF_DEL_RESULT_ABSENT:
+ goto absent;
}
- if (lex->spname->m_db.str == NULL)
+ DBUG_ASSERT("wrong return code" == 0);
+absent:
+ // If there was no current database, so it cannot be SP
+ if (!lex->spname->m_db.str)
{
if (lex->if_exists())
{
@@ -6681,7 +6734,7 @@ check_access(THD *thd, privilege_t want_access,
@param thd Thread handler
@param privilege requested privilege
- @param all_tables global table list of query
+ @param tables global table list of query
@param no_errors FALSE/TRUE - report/don't report error to
the client (using my_error() call).
@@ -6691,28 +6744,25 @@ check_access(THD *thd, privilege_t want_access,
1 access denied, error is sent to client
*/
-bool check_single_table_access(THD *thd, privilege_t privilege,
- TABLE_LIST *all_tables, bool no_errors)
+bool check_single_table_access(THD *thd, privilege_t privilege,
+ TABLE_LIST *tables, bool no_errors)
{
- Switch_to_definer_security_ctx backup_sctx(thd, all_tables);
+ Switch_to_definer_security_ctx backup_sctx(thd, tables);
const char *db_name;
- if ((all_tables->view || all_tables->field_translation) &&
- !all_tables->schema_table)
- db_name= all_tables->view_db.str;
+ if ((tables->view || tables->field_translation) && !tables->schema_table)
+ db_name= tables->view_db.str;
else
- db_name= all_tables->db.str;
+ db_name= tables->db.str;
- if (check_access(thd, privilege, db_name,
- &all_tables->grant.privilege,
- &all_tables->grant.m_internal,
- 0, no_errors))
+ if (check_access(thd, privilege, db_name, &tables->grant.privilege,
+ &tables->grant.m_internal, 0, no_errors))
return 1;
/* Show only 1 table for check_grant */
- if (!(all_tables->belong_to_view &&
- (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
- check_grant(thd, privilege, all_tables, FALSE, 1, no_errors))
+ if (!(tables->belong_to_view &&
+ (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
+ check_grant(thd, privilege, tables, FALSE, 1, no_errors))
return 1;
return 0;
@@ -7755,7 +7805,6 @@ static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
void mysql_parse(THD *thd, char *rawbuf, uint length,
Parser_state *parser_state)
{
- int error __attribute__((unused));
DBUG_ENTER("mysql_parse");
DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_MYSQLparse(););
DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on_ORAparse(););
@@ -7830,6 +7879,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
(char *) thd->security_ctx->host_or_ip,
0);
+ int error __attribute__((unused));
error= mysql_execute_command(thd);
MYSQL_QUERY_EXEC_DONE(error);
}
@@ -8928,8 +8978,6 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
SELECT_LEX *lex)
{
b->natural_join= a;
- a->part_of_natural_join= TRUE;
- b->part_of_natural_join= TRUE;
lex->prev_join_using= using_fields;
}
@@ -9795,7 +9843,7 @@ static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables)
if (is_temporary_table(table))
continue;
- if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, table,
+ if (check_table_access(thd, PRIV_LOCK_TABLES, table,
FALSE, 1, FALSE))
return TRUE;
}
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index 36dc68c292c..37861cf224f 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -41,7 +41,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
int mysql_multi_update_prepare(THD *thd);
int mysql_multi_delete_prepare(THD *thd);
-bool mysql_insert_select_prepare(THD *thd,select_result *sel_res);
+int mysql_insert_select_prepare(THD *thd,select_result *sel_res);
bool update_precheck(THD *thd, TABLE_LIST *tables);
bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 6753b857b54..57d6b27fcbb 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -124,6 +124,9 @@ When one supplies long data for a placeholder:
#include "mysql/psi/mysql_ps.h" // MYSQL_EXECUTE_PS
#include "wsrep_mysqld.h"
+/* Constants defining bits in parameter type flags. Flags are read from high byte of short value */
+static const uint PARAMETER_FLAG_UNSIGNED = 128U << 8;
+
/**
A result class used to send cursor rows using the binary protocol.
*/
@@ -897,11 +900,73 @@ static bool insert_bulk_params(Prepared_statement *stmt,
DBUG_RETURN(0);
}
-static bool set_conversion_functions(Prepared_statement *stmt,
- uchar **data, uchar *data_end)
+
+/**
+ Checking if parameter type and flags are valid
+
+ @param typecode ushort value with type in low byte, and flags in high byte
+
+ @retval true this parameter is wrong
+ @retval false this parameter is OK
+*/
+
+static bool
+parameter_type_sanity_check(ushort typecode)
+{
+ /* Checking if type in lower byte is valid */
+ switch (typecode & 0xff) {
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ case MYSQL_TYPE_NULL:
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_GEOMETRY:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_NEWDATE:
+ break;
+ /*
+ This types normally cannot be sent by client, so maybe it'd be
+ better to treat them like an error here.
+ */
+ case MYSQL_TYPE_TIMESTAMP2:
+ case MYSQL_TYPE_TIME2:
+ case MYSQL_TYPE_DATETIME2:
+ default:
+ return true;
+ };
+
+ // In Flags in high byte only unsigned bit may be set
+ if (typecode & ((~PARAMETER_FLAG_UNSIGNED) & 0x0000ff00))
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool
+set_conversion_functions(Prepared_statement *stmt, uchar **data)
{
uchar *read_pos= *data;
- const uint signed_bit= 1 << 15;
+
DBUG_ENTER("set_conversion_functions");
/*
First execute or types altered by the client, setup the
@@ -914,12 +979,17 @@ static bool set_conversion_functions(Prepared_statement *stmt,
{
ushort typecode;
- if (read_pos >= data_end)
- DBUG_RETURN(1);
-
+ /*
+ stmt_execute_packet_sanity_check has already verified, that there
+ are enough data in the packet for data types
+ */
typecode= sint2korr(read_pos);
read_pos+= 2;
- (**it).unsigned_flag= MY_TEST(typecode & signed_bit);
+ if (parameter_type_sanity_check(typecode))
+ {
+ DBUG_RETURN(1);
+ }
+ (**it).unsigned_flag= MY_TEST(typecode & PARAMETER_FLAG_UNSIGNED);
(*it)->setup_conversion(thd, (uchar) (typecode & 0xff));
(*it)->sync_clones();
}
@@ -929,7 +999,7 @@ static bool set_conversion_functions(Prepared_statement *stmt,
static bool setup_conversion_functions(Prepared_statement *stmt,
- uchar **data, uchar *data_end,
+ uchar **data,
bool bulk_protocol= 0)
{
/* skip null bits */
@@ -942,7 +1012,7 @@ static bool setup_conversion_functions(Prepared_statement *stmt,
if (*read_pos++) //types supplied / first execute
{
*data= read_pos;
- bool res= set_conversion_functions(stmt, data, data_end);
+ bool res= set_conversion_functions(stmt, data);
DBUG_RETURN(res);
}
*data= read_pos;
@@ -1243,9 +1313,8 @@ static bool mysql_test_insert(Prepared_statement *stmt,
table_list->table->insert_values=(uchar *)1;
}
- if (mysql_prepare_insert(thd, table_list, table_list->table,
- fields, values, update_fields, update_values,
- duplic, &unused_conds, FALSE))
+ if (mysql_prepare_insert(thd, table_list, fields, values, update_fields,
+ update_values, duplic, &unused_conds, FALSE))
goto error;
value_count= values->elements;
@@ -2618,6 +2687,15 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
if (stmt->prepare(packet, packet_length))
{
+ /*
+ Prepare failed and stmt will be freed.
+ Now we have to save the query_string in the so the
+ audit plugin later gets the meaningful notification.
+ */
+ if (alloc_query(thd, stmt->query_string.str(), stmt->query_string.length()))
+ {
+ thd->set_query(0, 0);
+ }
/* Statement map deletes statement on erase */
thd->stmt_map.erase(stmt);
thd->clear_last_stmt();
@@ -2752,6 +2830,7 @@ bool Lex_prepared_stmt::get_dynamic_sql_string(THD *thd,
void mysql_sql_stmt_prepare(THD *thd)
{
LEX *lex= thd->lex;
+ CSET_STRING orig_query= thd->query_string;
const LEX_CSTRING *name= &lex->prepared_stmt.name();
Prepared_statement *stmt;
LEX_CSTRING query;
@@ -2822,7 +2901,16 @@ void mysql_sql_stmt_prepare(THD *thd)
thd->m_statement_psi,
stmt->name.str, stmt->name.length);
- if (stmt->prepare(query.str, (uint) query.length))
+ bool res= stmt->prepare(query.str, (uint) query.length);
+ /*
+ stmt->prepare() sets thd->query_string with the prepared
+ query, so the audit plugin gets adequate notification with the
+ mysqld_stmt_* set of functions.
+ But here we should restore the original query so it's mentioned in
+ logs properly.
+ */
+ thd->set_query(orig_query);
+ if (res)
{
/* Statement map deletes the statement on erase */
thd->stmt_map.erase(stmt);
@@ -2841,6 +2929,7 @@ void mysql_sql_stmt_prepare(THD *thd)
void mysql_sql_stmt_execute_immediate(THD *thd)
{
LEX *lex= thd->lex;
+ CSET_STRING orig_query= thd->query_string;
Prepared_statement *stmt;
LEX_CSTRING query;
DBUG_ENTER("mysql_sql_stmt_execute_immediate");
@@ -2889,6 +2978,14 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
thd->free_items();
thd->free_list= free_list_backup;
+ /*
+ stmt->execute_immediately() sets thd->query_string with the executed
+ query, so the audit plugin gets adequate notification with the
+ mysqld_stmt_* set of functions.
+ But here we should restore the original query so it's mentioned in
+ logs properly.
+ */
+ thd->set_query_inner(orig_query);
stmt->lex->restore_set_statement_var();
delete stmt;
DBUG_VOID_RETURN;
@@ -3110,11 +3207,19 @@ static void mysql_stmt_execute_common(THD *thd,
void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
{
+ const uint packet_min_lenght= 9;
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
+
+ DBUG_ENTER("mysqld_stmt_execute");
+
+ if (packet_length < packet_min_lenght)
+ {
+ my_error(ER_MALFORMED_PACKET, MYF(0));
+ DBUG_VOID_RETURN;
+ }
ulong stmt_id= uint4korr(packet);
ulong flags= (ulong) packet[4];
uchar *packet_end= packet + packet_length;
- DBUG_ENTER("mysqld_stmt_execute");
packet+= 9; /* stmt_id + 5 bytes of flags */
@@ -3170,6 +3275,84 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
DBUG_VOID_RETURN;
}
+/**
+ Additional packet checks for direct execution
+
+ @param thd THD handle
+ @param stmt prepared statement being directly executed
+ @param paket packet with parameters to bind
+ @param packet_end pointer to the byte after parameters end
+ @param bulk_op is it bulk operation
+ @param direct_exec is it direct execution
+ @param read_bytes need to read types (only with bulk_op)
+
+ @retval true this parameter is wrong
+ @retval false this parameter is OK
+*/
+
+static bool
+stmt_execute_packet_sanity_check(Prepared_statement *stmt,
+ uchar *packet, uchar *packet_end,
+ bool bulk_op, bool direct_exec,
+ bool read_types)
+{
+
+ DBUG_ASSERT((!read_types) || (read_types && bulk_op));
+ if (stmt->param_count > 0)
+ {
+ uint packet_length= static_cast<uint>(packet_end - packet);
+ uint null_bitmap_bytes= (bulk_op ? 0 : (stmt->param_count + 7)/8);
+ uint min_len_for_param_count = null_bitmap_bytes
+ + (bulk_op ? 0 : 1); /* sent types byte */
+
+ if (!bulk_op && packet_length >= min_len_for_param_count)
+ {
+ if ((read_types= packet[null_bitmap_bytes]))
+ {
+ /*
+ Should be 0 or 1. If the byte is not 1, that could mean,
+ e.g. that we read incorrect byte due to incorrect number
+ of sent parameters for direct execution (i.e. null bitmap
+ is shorter or longer, than it should be)
+ */
+ if (packet[null_bitmap_bytes] != '\1')
+ {
+ return true;
+ }
+ }
+ }
+
+ if (read_types)
+ {
+ /* 2 bytes per parameter of the type and flags */
+ min_len_for_param_count+= 2*stmt->param_count;
+ }
+ else
+ {
+ /*
+ If types are not sent, there is nothing to do here.
+ But for direct execution types should always be sent
+ */
+ return direct_exec;
+ }
+
+ /*
+ If true, the packet is guaranteed too short for the number of
+ parameters in the PS
+ */
+ return (packet_length < min_len_for_param_count);
+ }
+ else
+ {
+ /*
+ If there is no parameters, this should be normally already end
+ of the packet. If it's not - then error
+ */
+ return (packet_end > packet);
+ }
+ return false;
+}
+
/**
Common part of prepared statement execution
@@ -3205,10 +3388,33 @@ static void mysql_stmt_execute_common(THD *thd,
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
char llbuf[22];
+ /*
+ Did not find the statement with the provided stmt_id.
+ Set thd->query_string with the stmt_id so the
+ audit plugin gets the meaningful notification.
+ */
+ if (alloc_query(thd, llbuf, strlen(llbuf)))
+ thd->set_query(0, 0);
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
llstr(stmt_id, llbuf), "mysqld_stmt_execute");
DBUG_VOID_RETURN;
}
+
+ /*
+ In case of direct execution application decides how many parameters
+ to send.
+
+ Thus extra checks are required to prevent crashes caused by incorrect
+ interpretation of the packet data. Plus there can be always a broken
+ evil client.
+ */
+ if (stmt_execute_packet_sanity_check(stmt, packet, packet_end, bulk_op,
+ stmt_id == LAST_STMT_ID, read_types))
+ {
+ my_error(ER_MALFORMED_PACKET, MYF(0));
+ DBUG_VOID_RETURN;
+ }
+
stmt->read_types= read_types;
#if defined(ENABLED_PROFILING)
@@ -3969,6 +4175,19 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
DBUG_RETURN(TRUE);
}
+ /*
+ We'd like to have thd->query to be set to the actual query
+ after the function ends.
+ This value will be sent to audit plugins later.
+ As the statement is created, the query will be stored
+ in statement's arena. Normally the statement lives longer than
+ the end of this query, so we can just set thd->query_string to
+ be the stmt->query_string.
+ Though errors can result in statement to be freed. These cases
+ should be handled appropriately.
+ */
+ stmt_backup.query_string= thd->query_string;
+
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
@@ -4131,7 +4350,7 @@ Prepared_statement::set_parameters(String *expanded_query,
{
#ifndef EMBEDDED_LIBRARY
uchar *null_array= packet;
- res= (setup_conversion_functions(this, &packet, packet_end) ||
+ res= (setup_conversion_functions(this, &packet) ||
set_params(this, null_array, packet, packet_end, expanded_query));
#else
/*
@@ -4321,7 +4540,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
return TRUE;
}
- if (!(sql_command_flags[lex->sql_command] & CF_SP_BULK_SAFE))
+ if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_SAFE))
{
DBUG_PRINT("error", ("Command is not supported in bulk execution."));
my_error(ER_UNSUPPORTED_PS, MYF(0));
@@ -4331,7 +4550,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
#ifndef EMBEDDED_LIBRARY
if (read_types &&
- set_conversion_functions(this, &packet, packet_end))
+ set_conversion_functions(this, &packet))
#else
// bulk parameters are not supported for embedded, so it will an error
#endif
@@ -4353,7 +4572,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
Here we set parameters for not optimized commands,
optimized commands do it inside thier internal loop.
*/
- if (!(sql_command_flags[lex->sql_command] & CF_SP_BULK_OPTIMIZED))
+ if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED))
{
if (set_bulk_parameters(TRUE))
{
@@ -4504,6 +4723,15 @@ Prepared_statement::reprepare()
*/
thd->get_stmt_da()->clear_warning_info(thd->query_id);
}
+ else
+ {
+ /*
+ Prepare failed and the 'copy' will be freed.
+ Now we have to restore the query_string in the so the
+ audit plugin later gets the meaningful notification.
+ */
+ thd->set_query(query(), query_length());
+ }
return error;
}
@@ -5127,7 +5355,7 @@ public:
Protocol_local(THD *thd_arg, ulong prealloc= 0) :
Protocol_text(thd_arg, prealloc),
- cur_data(0), first_data(0), data_tail(&first_data)
+ cur_data(0), first_data(0), data_tail(&first_data), alloc(0)
{}
protected:
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index ae5a26e1529..8f87d633d19 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -218,6 +218,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
thd->handler_tables_hash.records ||
thd->ull_hash.records ||
thd->global_read_lock.is_acquired() ||
+ thd->mdl_backup_lock ||
thd->current_backup_stage != BACKUP_FINISHED
);
@@ -530,7 +531,14 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (thd->current_backup_stage != BACKUP_FINISHED)
{
my_error(ER_BACKUP_LOCK_IS_ACTIVE, MYF(0));
- return true;
+ goto error;
+ }
+
+ /* Should not flush tables while BACKUP LOCK is active */
+ if (thd->mdl_backup_lock)
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ goto error;
}
if (thd->lex->type & REFRESH_READ_LOCK)
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 0ac97bbeafd..77a1e46a75a 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -303,7 +303,8 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db,
DBUG_RETURN(skip_error || if_exists ? 0 : 1);
}
- if (ha_check_if_updates_are_ignored(thd, hton, "RENAME"))
+ if (hton != view_pseudo_hton &&
+ ha_check_if_updates_are_ignored(thd, hton, "RENAME"))
{
/*
Shared table. Just drop the old .frm as it's not correct anymore
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 420a64ba827..74b9b4dc393 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -439,11 +439,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. */
@@ -743,7 +746,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
void vers_select_conds_t::print(String *str, enum_query_type query_type) const
{
- switch (type) {
+ switch (orig_type) {
case SYSTEM_TIME_UNSPECIFIED:
break;
case SYSTEM_TIME_AS_OF:
@@ -991,6 +994,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
case SQLCOM_SELECT:
use_sysvar= true;
/* fall through */
+ case SQLCOM_CREATE_TABLE:
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_DELETE_MULTI:
@@ -1608,7 +1612,7 @@ int JOIN::optimize()
if (!(select_options & SELECT_DESCRIBE))
{
/* Prepare to execute the query pushed into a foreign engine */
- res= select_lex->pushdown_select->init();
+ res= select_lex->pushdown_select->prepare();
}
with_two_phase_optimization= false;
}
@@ -2781,6 +2785,10 @@ int JOIN::optimize_stage2()
(select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
(select_lex->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0);
+ if (select_lex->options & OPTION_SCHEMA_TABLE &&
+ optimize_schema_tables_reads(this))
+ DBUG_RETURN(1);
+
if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after))
DBUG_RETURN(1);
@@ -2957,10 +2965,6 @@ int JOIN::optimize_stage2()
having_is_correlated= MY_TEST(having->used_tables() & OUTER_REF_TABLE_BIT);
tmp_having= having;
- if ((select_lex->options & OPTION_SCHEMA_TABLE) &&
- optimize_schema_tables_reads(this))
- DBUG_RETURN(TRUE);
-
if (unlikely(thd->is_error()))
DBUG_RETURN(TRUE);
@@ -4642,19 +4646,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
}
/* Look for a table owned by an engine with the select_handler interface */
- select_lex->select_h= select_lex->find_select_handler(thd);
- if (select_lex->select_h)
- {
- /* Create a Pushdown_select object for later execution of the query */
- if (!(select_lex->pushdown_select=
- new (thd->mem_root) Pushdown_select(select_lex,
- select_lex->select_h)))
- {
- delete select_lex->select_h;
- select_lex->select_h= NULL;
- DBUG_RETURN(TRUE);
- }
- }
+ select_lex->pushdown_select= select_lex->find_select_handler(thd);
if ((err= join->optimize()))
{
@@ -18161,8 +18153,7 @@ public:
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
- const ST_SCHEMA_TABLE &schema_table,
- const MY_BITMAP &bitmap);
+ const ST_SCHEMA_TABLE &schema_table);
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
@@ -18271,8 +18262,7 @@ TABLE *Create_tmp_table::start(THD *thd,
No need to change table name to lower case as we are only creating
MyISAM, Aria or HEAP tables here
*/
- fn_format(path, path, mysql_tmpdir, "",
- MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (m_group)
{
@@ -19094,8 +19084,7 @@ err:
bool Create_tmp_table::add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
- const ST_SCHEMA_TABLE &schema_table,
- const MY_BITMAP &bitmap)
+ const ST_SCHEMA_TABLE &schema_table)
{
DBUG_ENTER("Create_tmp_table::add_schema_fields");
DBUG_ASSERT(table);
@@ -19114,11 +19103,9 @@ bool Create_tmp_table::add_schema_fields(THD *thd, TABLE *table,
for (fieldnr= 0; !defs[fieldnr].end_marker(); fieldnr++)
{
const ST_FIELD_INFO &def= defs[fieldnr];
- bool visible= bitmap_is_set(&bitmap, fieldnr);
Record_addr addr(def.nullable());
const Type_handler *h= def.type_handler();
- Field *field= h->make_schema_field(&table->mem_root, table,
- addr, def, visible);
+ Field *field= h->make_schema_field(&table->mem_root, table, addr, def);
if (!field)
{
thd->mem_root= mem_root_save;
@@ -19181,17 +19168,16 @@ TABLE *create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
- const MY_BITMAP &bitmap,
longlong select_options,
const LEX_CSTRING &table_alias,
- bool keep_row_order)
+ bool do_not_open, bool keep_row_order)
{
TABLE *table;
Create_tmp_table maker(param, (ORDER *) NULL, false, false,
select_options, HA_POS_ERROR);
if (!(table= maker.start(thd, param, &table_alias)) ||
- maker.add_schema_fields(thd, table, param, schema_table, bitmap) ||
- maker.finalize(thd, table, param, false, keep_row_order))
+ maker.add_schema_fields(thd, table, param, schema_table) ||
+ maker.finalize(thd, table, param, do_not_open, keep_row_order))
{
maker.cleanup_on_failure(thd, table);
return NULL;
@@ -19572,14 +19558,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
}
- if (unlikely((error= maria_create(share->path.str,
- file_type,
- share->keys, &keydef,
- (uint) (*recinfo-start_recinfo),
- start_recinfo,
- share->uniques, &uniquedef,
- &create_info,
- create_flags))))
+ if (unlikely((error= maria_create(share->path.str, file_type, share->keys,
+ &keydef, (uint) (*recinfo-start_recinfo),
+ start_recinfo, share->uniques, &uniquedef,
+ &create_info, create_flags))))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
table->db_stat=0;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 2087438e086..2aba63ddc79 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -2436,10 +2436,9 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool keep_row_order= FALSE);
TABLE *create_tmp_table_for_schema(THD *thd, TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
- const MY_BITMAP &bitmap,
longlong select_options,
const LEX_CSTRING &alias,
- bool keep_row_order);
+ bool do_not_open, bool keep_row_order);
void free_tmp_table(THD *thd, TABLE *entry);
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
@@ -2517,29 +2516,6 @@ public:
class select_handler;
-class Pushdown_select: public Sql_alloc
-{
-private:
- bool is_analyze;
- List<Item> result_columns;
- bool send_result_set_metadata();
- bool send_data();
- bool send_eof();
-
-public:
- SELECT_LEX *select;
- select_handler *handler;
-
- Pushdown_select(SELECT_LEX *sel, select_handler *h);
-
- ~Pushdown_select();
-
- bool init();
-
- int execute();
-};
-
-
bool test_if_order_compatible(SQL_I_List<ORDER> &a, SQL_I_List<ORDER> &b);
int test_if_group_changed(List<Cached_item> &list);
int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1e32e8b2925..c00476871e4 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3675,8 +3675,6 @@ static bool show_status_array(THD *thd, const char *wild,
CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array");
- thd->count_cuted_fields= CHECK_FIELD_WARN;
-
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
if (*prefix)
*prefix_end++= '_';
@@ -3776,6 +3774,8 @@ static bool show_status_array(THD *thd, const char *wild,
pos= get_one_variable(thd, var, scope, show_type, status_var,
&charset, buff, &length);
+ if (table->field[1]->field_length)
+ thd->count_cuted_fields= CHECK_FIELD_WARN;
table->field[1]->store(pos, (uint32) length, charset);
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
table->field[1]->set_notnull();
@@ -5251,6 +5251,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
free_root(&tmp_mem_root, MY_MARK_BLOCKS_FREE);
}
}
+ if (thd->killed == ABORT_QUERY)
+ {
+ error= 0;
+ goto err;
+ }
}
}
}
@@ -8041,51 +8046,6 @@ ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
return &schema_tables[schema_table_idx];
}
-static void
-mark_all_fields_used_in_query(THD *thd,
- ST_FIELD_INFO *schema_fields,
- MY_BITMAP *bitmap,
- Item *all_items)
-{
- Item *item;
- DBUG_ENTER("mark_all_fields_used_in_query");
-
- /* If not SELECT command, return all columns */
- if (thd->lex->sql_command != SQLCOM_SELECT &&
- thd->lex->sql_command != SQLCOM_SET_OPTION)
- {
- bitmap_set_all(bitmap);
- DBUG_VOID_RETURN;
- }
-
- for (item= all_items ; item ; item= item->next)
- {
- if (item->type() == Item::FIELD_ITEM)
- {
- ST_FIELD_INFO *fields= schema_fields;
- uint count;
- Item_field *item_field= (Item_field*) item;
-
- /* item_field can be '*' as this function is called before fix_fields */
- if (item_field->field_name.str == star_clex_str.str)
- {
- bitmap_set_all(bitmap);
- break;
- }
- for (count=0; !fields->end_marker(); fields++, count++)
- {
- if (!my_strcasecmp(system_charset_info, fields->name().str,
- item_field->field_name.str))
- {
- bitmap_set_bit(bitmap, count);
- break;
- }
- }
- }
- }
- DBUG_VOID_RETURN;
-}
-
/**
Create information_schema table using schema_table data.
@@ -8098,7 +8058,7 @@ mark_all_fields_used_in_query(THD *thd,
0<decimals<10 and 0<=length<100 .
@param
- thd thread handler
+ thd thread handler
@param table_list Used to pass I_S table information(fields info, tables
parameters etc) and table name.
@@ -8109,32 +8069,16 @@ mark_all_fields_used_in_query(THD *thd,
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
{
- uint field_count;
- Item *all_items;
+ uint field_count= 0;
TABLE *table;
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
- ST_FIELD_INFO *fields_info= schema_table->fields_info;
- ST_FIELD_INFO *fields;
- MY_BITMAP bitmap;
- my_bitmap_map *buf;
+ ST_FIELD_INFO *fields= schema_table->fields_info;
+ bool need_all_fieds= table_list->schema_table_reformed || // SHOW command
+ thd->lex->only_view_structure(); // need table structure
DBUG_ENTER("create_schema_table");
- for (field_count= 0, fields= fields_info; !fields->end_marker(); fields++)
+ for (; !fields->end_marker(); fields++)
field_count++;
- if (!(buf= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count))))
- DBUG_RETURN(NULL);
- my_bitmap_init(&bitmap, buf, field_count, 0);
-
- if (!thd->stmt_arena->is_conventional() &&
- thd->mem_root != thd->stmt_arena->mem_root)
- all_items= thd->stmt_arena->free_list;
- else
- all_items= thd->free_list;
-
- if (table_list->part_of_natural_join)
- bitmap_set_all(&bitmap);
- else
- mark_all_fields_used_in_query(thd, fields_info, &bitmap, all_items);
TMP_TABLE_PARAM *tmp_table_param = new (thd->mem_root) TMP_TABLE_PARAM;
tmp_table_param->init();
@@ -8143,13 +8087,9 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= table_list->select_lex;
bool keep_row_order= is_show_command(thd);
- if (!(table= create_tmp_table_for_schema(thd, tmp_table_param,
- *schema_table, bitmap,
- (select_lex->options |
- thd->variables.option_bits |
- TMP_TABLE_ALL_COLUMNS),
- table_list->alias,
- keep_row_order)))
+ if (!(table= create_tmp_table_for_schema(thd, tmp_table_param, *schema_table,
+ (select_lex->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS),
+ table_list->alias, !need_all_fieds, keep_row_order)))
DBUG_RETURN(0);
my_bitmap_map* bitmaps=
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
@@ -8541,6 +8481,68 @@ end:
}
+static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list)
+{
+ TABLE *table= table_list->table;
+ THD *thd=table->in_use;
+ if (!table->is_created())
+ {
+ TMP_TABLE_PARAM *p= table_list->schema_table_param;
+ TMP_ENGINE_COLUMNDEF *from_recinfo, *to_recinfo;
+ DBUG_ASSERT(table->s->keys == 0);
+ DBUG_ASSERT(table->s->uniques == 0);
+
+ // XXX HACK HACK HACK: in a stored function, RETURN (SELECT ...)
+ // enables warnings (in THD::sp_eval_expr) for the whole val_xxx/store pair,
+ // while the intention is to warn only for store(). Until this is
+ // fixed let's avoid data truncation warnings in I_S->fill_table()
+ if (thd->count_cuted_fields == CHECK_FIELD_IGNORE)
+ {
+
+ uchar *cur= table->field[0]->ptr;
+ /* first recinfo could be a NULL bitmap, not an actual Field */
+ from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]);
+ for (uint i=0; i < table->s->fields; i++, from_recinfo++)
+ {
+ Field *field= table->field[i];
+ DBUG_ASSERT(field->vcol_info == 0);
+ DBUG_ASSERT(from_recinfo->length);
+ DBUG_ASSERT(from_recinfo->length == field->pack_length_in_rec());
+ if (bitmap_is_set(table->read_set, i))
+ {
+ field->move_field(cur);
+ *to_recinfo++= *from_recinfo;
+ cur+= from_recinfo->length;
+ }
+ else
+ {
+ field= new (thd->mem_root) Field_string(cur, 0, field->null_ptr,
+ field->null_bit, Field::NONE,
+ &field->field_name, field->dtcollation());
+ field->init(table);
+ field->field_index= i;
+ DBUG_ASSERT(field->pack_length_in_rec() == 0);
+ table->field[i]= field;
+ }
+ }
+ if ((table->s->reclength= (ulong)(cur - table->record[0])) == 0)
+ {
+ /* all fields were optimized away. Force a non-0-length row */
+ table->s->reclength= to_recinfo->length= 1;
+ to_recinfo++;
+ }
+ p->recinfo= to_recinfo;
+ } // XXX end of HACK HACK HACK
+
+ // TODO switch from Aria to Memory if all blobs were optimized away?
+ if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo,
+ table_list->select_lex->options | thd->variables.option_bits))
+ return 1;
+ }
+ return 0;
+}
+
+
/*
This is the optimizer part of get_schema_tables_result().
*/
@@ -8561,6 +8563,9 @@ bool optimize_schema_tables_reads(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_information_schema_tables())
{
+ if (optimize_schema_tables_memory_usage(table_list))
+ DBUG_RETURN(1);
+
/* A value of 0 indicates a dummy implementation */
if (table_list->schema_table->fill_table == 0)
continue;
@@ -8583,10 +8588,10 @@ bool optimize_schema_tables_reads(JOIN *join)
cond= tab->cache_select->cond;
}
if (optimize_for_get_all_tables(thd, table_list, cond))
- DBUG_RETURN(TRUE); // Handle OOM
+ DBUG_RETURN(1); // Handle OOM
}
}
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(0);
}
@@ -8651,13 +8656,10 @@ bool get_schema_tables_result(JOIN *join,
continue;
/*
- If schema table is already processed and
- the statement is not a subselect then
- we don't need to fill this table again.
- If schema table is already processed and
- schema_table_state != executed_place then
- table is already processed and
- we should skip second data processing.
+ If schema table is already processed and the statement is not a
+ subselect then we don't need to fill this table again. If schema table
+ is already processed and schema_table_state != executed_place then
+ table is already processed and we should skip second data processing.
*/
if (table_list->schema_table_state &&
(!is_subselect || table_list->schema_table_state != executed_place))
@@ -8719,8 +8721,7 @@ bool get_schema_tables_result(JOIN *join,
It also means that an audit plugin cannot process the error correctly
either. See also thd->clear_error()
*/
- thd->get_stmt_da()->push_warning(thd,
- thd->get_stmt_da()->sql_errno(),
+ thd->get_stmt_da()->push_warning(thd, thd->get_stmt_da()->sql_errno(),
thd->get_stmt_da()->get_sqlstate(),
Sql_condition::WARN_LEVEL_ERROR,
thd->get_stmt_da()->message());
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
index 3230052dd84..3b23328183c 100644
--- a/sql/sql_sort.h
+++ b/sql/sql_sort.h
@@ -255,10 +255,12 @@ class Sort_keys :public Sql_alloc,
{
public:
Sort_keys(SORT_FIELD* arr, size_t count):
- Sort_keys_array(arr, count),
- m_using_packed_sortkeys(false),
- size_of_packable_fields(0),
- sort_length(0)
+ Sort_keys_array(arr, count),
+ m_using_packed_sortkeys(false),
+ size_of_packable_fields(0),
+ sort_length_with_original_values(0),
+ sort_length_with_memcmp_values(0),
+ parameters_computed(false)
{
DBUG_ASSERT(!is_null());
}
@@ -280,14 +282,24 @@ public:
return size_of_packable_fields;
}
- void set_sort_length(uint len)
+ void set_sort_length_with_original_values(uint len)
{
- sort_length= len;
+ sort_length_with_original_values= len;
}
- uint get_sort_length()
+ uint get_sort_length_with_original_values()
{
- return sort_length;
+ return sort_length_with_original_values;
+ }
+
+ void set_sort_length_with_memcmp_values(uint len)
+ {
+ sort_length_with_memcmp_values= len;
+ }
+
+ uint get_sort_length_with_memcmp_values()
+ {
+ return sort_length_with_memcmp_values;
}
static void store_sortkey_length(uchar *p, uint sz)
@@ -307,9 +319,12 @@ public:
void increment_original_sort_length(uint len)
{
- sort_length+= len;
+ sort_length_with_original_values+= len;
}
+ bool is_parameters_computed() { return parameters_computed; }
+ void set_parameters_computed(bool val) { parameters_computed= val; }
+
static const uint size_of_length_field= 4;
private:
@@ -317,10 +332,21 @@ private:
uint size_of_packable_fields; // Total length bytes for packable columns
/*
- The length that would be needed if we stored non-packed mem-comparable
- images of fields?
+ The sort length for all the keyparts storing the original values
+ */
+ uint sort_length_with_original_values;
+
+ /*
+ The sort length for all the keyparts storing the mem-comparable images
+ */
+ uint sort_length_with_memcmp_values;
+
+ /*
+ TRUE parameters(like sort_length_* , size_of_packable_field)
+ are computed
+ FALSE otherwise.
*/
- uint sort_length;
+ bool parameters_computed;
};
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index e2defba434d..94f2e6fc8c6 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -767,10 +767,10 @@ void Static_binary_string::qs_append(double d)
NULL);
}
-void Static_binary_string::qs_append(double *d)
+void Static_binary_string::qs_append(const double *d)
{
double ld;
- float8get(ld, (char*) d);
+ float8get(ld, (const char*) d);
qs_append(ld);
}
@@ -858,7 +858,7 @@ int sortcmp(const String *s,const String *t, CHARSET_INFO *cs)
int stringcmp(const String *s,const String *t)
{
uint32 s_len=s->length(),t_len=t->length(),len=MY_MIN(s_len,t_len);
- int cmp= memcmp(s->ptr(), t->ptr(), len);
+ int cmp= len ? memcmp(s->ptr(), t->ptr(), len) : 0;
return (cmp) ? cmp : (int) (s_len - t_len);
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 2ef817ea0ad..b3eca118b63 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -314,7 +314,8 @@ public:
}
void q_append(const char *data, size_t data_len)
{
- memcpy(Ptr + str_length, data, data_len);
+ if (data_len)
+ memcpy(Ptr + str_length, data, data_len);
DBUG_ASSERT(str_length <= UINT_MAX32 - data_len);
str_length += (uint)data_len;
}
@@ -345,7 +346,7 @@ public:
void qs_append(const char *str, size_t len);
void qs_append_hex(const char *str, uint32 len);
void qs_append(double d);
- void qs_append(double *d);
+ void qs_append(const double *d);
inline void qs_append(const char c)
{
Ptr[str_length]= c;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 15d190c3139..c2ba9bcadfb 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -75,9 +75,8 @@ static int copy_data_between_tables(THD *, TABLE *,TABLE *,
ha_rows *, ha_rows *,
Alter_info::enum_enable_or_disable,
Alter_table_ctx *);
-static bool append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
- Alter_info *alter_info, KEY **key_info,
- uint key_count);
+static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
+ Key *key);
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
uint *, handler *, KEY **, uint *, int);
static uint blob_length_by_type(enum_field_types type);
@@ -1823,10 +1822,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
if (flags & WFRM_WRITE_SHADOW)
{
- if (append_system_key_parts(lpt->thd, lpt->create_info, lpt->alter_info,
- &lpt->key_info_buffer, 0))
- DBUG_RETURN(true);
-
if (mysql_prepare_create_table(lpt->thd, lpt->create_info, lpt->alter_info,
&lpt->db_options, lpt->table->file,
&lpt->key_info_buffer, &lpt->key_count,
@@ -2828,6 +2823,12 @@ bool log_drop_table(THD *thd, const LEX_CSTRING *db_name,
append_identifier(thd, &query, table_name);
query.append(STRING_WITH_LEN("/* Generated to handle "
"failed CREATE OR REPLACE */"));
+
+ /*
+ In case of temporary tables we don't have to log the database name
+ in the binary log. We log this for non temporary tables, as the slave
+ may use a filter to ignore queries for a specific database.
+ */
error= thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
FALSE, FALSE, temporary_table, 0) > 0;
@@ -3451,10 +3452,9 @@ Key *
mysql_add_invisible_index(THD *thd, List<Key> *key_list,
LEX_CSTRING* field_name, enum Key::Keytype type)
{
- Key *key= NULL;
- key= new (thd->mem_root) Key(type, &null_clex_str, HA_KEY_ALG_UNDEF,
- false, DDL_options(DDL_options::OPT_NONE));
- key->columns.push_back(new(thd->mem_root) Key_part_spec(field_name, 0),
+ Key *key= new (thd->mem_root) Key(type, &null_clex_str, HA_KEY_ALG_UNDEF,
+ false, DDL_options(DDL_options::OPT_NONE));
+ key->columns.push_back(new(thd->mem_root) Key_part_spec(field_name, 0, true),
thd->mem_root);
key_list->push_back(key, thd->mem_root);
return key;
@@ -3552,7 +3552,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Create_field *sql_field,*dup_field;
uint field,null_fields,max_key_length;
ulong record_offset= 0;
- KEY *key_info;
KEY_PART_INFO *key_part_info;
int field_no,dup_no;
int select_field_pos,auto_increment=0;
@@ -3870,6 +3869,57 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
thd->abort_on_warning= sav_abort_on_warning;
}
}
+
+ KEY *key_info= *key_info_buffer= (KEY*)thd->calloc(sizeof(KEY) * (*key_count));
+ if (!*key_info_buffer)
+ DBUG_RETURN(true); // Out of memory
+
+ key_iterator.rewind();
+ while ((key=key_iterator++))
+ {
+ if (key->name.str == ignore_key || key->type == Key::FOREIGN_KEY)
+ continue;
+ /* Create the key->ame based on the first column (if not given) */
+ if (key->type == Key::PRIMARY)
+ {
+ if (primary_key)
+ {
+ my_message(ER_MULTIPLE_PRI_KEY, ER_THD(thd, ER_MULTIPLE_PRI_KEY),
+ MYF(0));
+ DBUG_RETURN(true);
+ }
+ key_name=primary_key_name;
+ primary_key=1;
+ }
+ else if (!(key_name= key->name.str))
+ {
+ auto field_name= key->columns.elem(0)->field_name;
+ it.rewind();
+ while ((sql_field=it++) &&
+ lex_string_cmp(system_charset_info,
+ &field_name,
+ &sql_field->field_name));
+ if (sql_field)
+ field_name= sql_field->field_name;
+ key_name=make_unique_key_name(thd, field_name.str,
+ *key_info_buffer, key_info);
+ }
+ if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
+ {
+ my_error(ER_DUP_KEYNAME, MYF(0), key_name);
+ DBUG_RETURN(true);
+ }
+
+ key_info->name.str= (char*) key_name;
+ key_info->name.length= strlen(key_name);
+ key->name= key_info->name;
+
+ int parts_added= append_system_key_parts(thd, create_info, key);
+ if (parts_added < 0)
+ DBUG_RETURN(true);
+ key_parts += parts_added;
+ key_info++;
+ }
tmp=file->max_keys();
if (*key_count > tmp)
{
@@ -3877,11 +3927,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE);
}
- (*key_info_buffer)= key_info= (KEY*) thd->calloc(sizeof(KEY) * (*key_count));
key_part_info=(KEY_PART_INFO*) thd->calloc(sizeof(KEY_PART_INFO)*key_parts);
- if (!*key_info_buffer || ! key_part_info)
- DBUG_RETURN(TRUE); // Out of memory
+ if (!key_part_info)
+ DBUG_RETURN(true); // Out of memory
+ key_info= *key_info_buffer;
key_iterator.rewind();
key_number=0;
for (; (key=key_iterator++) ; key_number++)
@@ -4028,7 +4078,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/*
Either field is not present or field visibility is > INVISIBLE_USER
*/
- if (!sql_field)
+ if (!sql_field || (sql_field->invisible > INVISIBLE_USER &&
+ !column->generated))
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
@@ -4251,32 +4302,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_length+= key_part_length;
key_part_info++;
-
- /* Create the key name based on the first column (if not given) */
- if (column_nr == 0)
- {
- if (key->type == Key::PRIMARY)
- {
- if (primary_key)
- {
- my_message(ER_MULTIPLE_PRI_KEY, ER_THD(thd, ER_MULTIPLE_PRI_KEY),
- MYF(0));
- DBUG_RETURN(TRUE);
- }
- key_name=primary_key_name;
- primary_key=1;
- }
- else if (!(key_name= key->name.str))
- key_name=make_unique_key_name(thd, sql_field->field_name.str,
- *key_info_buffer, key_info);
- if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
- {
- my_error(ER_DUP_KEYNAME, MYF(0), key_name);
- DBUG_RETURN(TRUE);
- }
- key_info->name.str= (char*) key_name;
- key_info->name.length= strlen(key_name);
- }
}
if (!key_info->name.str || check_column_name(key_info->name.str))
{
@@ -4709,69 +4734,75 @@ bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
}
-static bool append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
- Alter_info *alter_info, KEY **key_info,
- uint key_count)
+/**
+ Appends key parts generated by mariadb server.
+ Adds row_end in UNIQUE keys for system versioning,
+ and period fields for WITHOUT OVERLAPS.
+ @param thd Thread data
+ @param create_info Table create info
+ @param key Parsed key
+ @return a number of key parts added to key.
+ */
+static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
+ Key *key)
{
const Lex_ident &row_start_field= create_info->vers_info.as_row.start;
const Lex_ident &row_end_field= create_info->vers_info.as_row.end;
DBUG_ASSERT(!create_info->versioned() || (row_start_field && row_end_field));
- List_iterator<Key> key_it(alter_info->key_list);
- Key *key= NULL;
-
- if (create_info->versioned())
+ int result = 0;
+ if (create_info->versioned() && (key->type == Key::PRIMARY
+ || key->type == Key::UNIQUE))
{
- while ((key=key_it++))
+ Key_part_spec *key_part=NULL;
+ List_iterator<Key_part_spec> part_it(key->columns);
+ while ((key_part=part_it++))
{
- if (key->type != Key::PRIMARY && key->type != Key::UNIQUE)
- continue;
-
- Key_part_spec *key_part=NULL;
- List_iterator<Key_part_spec> part_it(key->columns);
- while ((key_part=part_it++))
- {
- if (row_start_field.streq(key_part->field_name) ||
- row_end_field.streq(key_part->field_name))
- break;
- }
- if (!key_part)
- key->columns.push_back(new Key_part_spec(&row_end_field, 0));
+ if (row_start_field.streq(key_part->field_name) ||
+ row_end_field.streq(key_part->field_name))
+ break;
}
- key_it.rewind();
+ if (!key_part)
+ {
+ key->columns.push_back(new (thd->mem_root)
+ Key_part_spec(&row_end_field, 0, true));
+ result++;
+ }
+
}
- while ((key=key_it++))
+ if (key->without_overlaps)
{
- if (key->without_overlaps)
+ DBUG_ASSERT(key->type == Key::PRIMARY || key->type == Key::UNIQUE);
+ if (!create_info->period_info.is_set()
+ || !key->period.streq(create_info->period_info.name))
{
- DBUG_ASSERT(key->type == Key::PRIMARY || key->type == Key::UNIQUE);
- if (!create_info->period_info.is_set()
- || !key->period.streq(create_info->period_info.name))
- {
- my_error(ER_PERIOD_NOT_FOUND, MYF(0), key->period.str);
- return true;
- }
+ my_error(ER_PERIOD_NOT_FOUND, MYF(0), key->period.str);
+ return -1;
+ }
- const auto &period_start= create_info->period_info.period.start;
- const auto &period_end= create_info->period_info.period.end;
- List_iterator<Key_part_spec> part_it(key->columns);
- while (Key_part_spec *key_part= part_it++)
+ const auto &period_start= create_info->period_info.period.start;
+ const auto &period_end= create_info->period_info.period.end;
+ List_iterator<Key_part_spec> part_it(key->columns);
+ while (Key_part_spec *key_part= part_it++)
+ {
+ if (period_start.streq(key_part->field_name)
+ || period_end.streq(key_part->field_name))
{
- if (period_start.streq(key_part->field_name)
- || period_end.streq(key_part->field_name))
- {
- my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key->name.str,
- key_part->field_name);
- return true;
- }
+ my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key->name.str,
+ key_part->field_name.str);
+ return -1;
}
- key->columns.push_back(new Key_part_spec(&period_end, 0));
- key->columns.push_back(new Key_part_spec(&period_start, 0));
}
+ const auto &period= create_info->period_info.period;
+ key->columns.push_back(new (thd->mem_root)
+ Key_part_spec(&period.end, 0, true));
+ key->columns.push_back(new (thd->mem_root)
+ Key_part_spec(&period.start, 0, true));
+ result += 2;
}
- return false;
+ return result;
}
handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
@@ -5009,10 +5040,6 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
}
#endif
- if (append_system_key_parts(thd, create_info, alter_info, key_info,
- *key_count))
- goto err;
-
if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options,
file, key_info, key_count, create_table_mode))
goto err;
@@ -5079,6 +5106,7 @@ int create_table_impl(THD *thd, const LEX_CSTRING &orig_db,
int error= 1;
bool frm_only= create_table_mode == C_ALTER_TABLE_FRM_ONLY;
bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || frm_only;
+ handlerton *exists_hton;
DBUG_ENTER("mysql_create_table_no_lock");
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d path: %s",
db.str, table_name.str, internal_tmp_table, path));
@@ -5167,8 +5195,16 @@ int create_table_impl(THD *thd, const LEX_CSTRING &orig_db,
goto err;
}
- if (!internal_tmp_table && ha_table_exists(thd, &db, &table_name))
+ if (!internal_tmp_table && ha_table_exists(thd, &db, &table_name,
+ &exists_hton))
{
+ if (ha_check_if_updates_are_ignored(thd, exists_hton, "CREATE"))
+ {
+ /* Don't create table. CREATE will still be logged in binary log */
+ error= 0;
+ goto err;
+ }
+
if (options.or_replace())
{
(void) delete_statistics_for_table(thd, &db, &table_name);
@@ -5196,7 +5232,8 @@ int create_table_impl(THD *thd, const LEX_CSTRING &orig_db,
thd->variables.option_bits|= OPTION_KEEP_LOG;
thd->log_current_statement= 1;
create_info->table_was_deleted= 1;
- DBUG_EXECUTE_IF("send_kill_after_delete", thd->set_killed(KILL_QUERY); );
+ DBUG_EXECUTE_IF("send_kill_after_delete",
+ thd->set_killed(KILL_QUERY); );
/*
Restart statement transactions for the case of CREATE ... SELECT.
@@ -5206,7 +5243,20 @@ int create_table_impl(THD *thd, const LEX_CSTRING &orig_db,
goto err;
}
else if (options.if_not_exists())
+ {
+ /*
+ We never come here as part of normal create table as table existance
+ is checked in open_and_lock_tables(). We may come here as part of
+ ALTER TABLE when converting a table for a distributed engine to a
+ a local one.
+ */
+
+ /* Log CREATE IF NOT EXISTS on slave for distributed engines */
+ if (thd->slave_thread && (exists_hton && exists_hton->flags &
+ HTON_IGNORE_UPDATES))
+ thd->log_current_statement= 1;
goto warn;
+ }
else
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name.str);
@@ -5437,12 +5487,21 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
thd->lex->create_info.options|= create_info->options;
/* Open or obtain an exclusive metadata lock on table being created */
+ create_table->db_type= 0;
result= open_and_lock_tables(thd, *create_info, create_table, FALSE, 0);
thd->lex->create_info.options= save_thd_create_info_options;
if (result)
{
+ if (thd->slave_thread &&
+ !thd->is_error() && create_table->db_type &&
+ (create_table->db_type->flags & HTON_IGNORE_UPDATES))
+ {
+ /* Table existed in distributed engine. Log query to binary log */
+ result= 0;
+ goto err;
+ }
/* is_error() may be 0 if table existed and we generated a warning */
DBUG_RETURN(thd->is_error());
}
@@ -5714,7 +5773,8 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
DBUG_ENTER("mysql_rename_table");
DBUG_ASSERT(base);
DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
- old_db->str, old_name->str, new_db->str, new_name->str));
+ old_db->str, old_name->str, new_db->str,
+ new_name->str));
// Temporarily disable foreign key checks
if (flags & NO_FK_CHECKS)
@@ -5724,8 +5784,8 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
build_table_filename(from, sizeof(from) - 1, old_db->str, old_name->str, "",
flags & FN_FROM_IS_TMP);
- length= build_table_filename(to, sizeof(to) - 1, new_db->str, new_name->str, "",
- flags & FN_TO_IS_TMP);
+ length= build_table_filename(to, sizeof(to) - 1, new_db->str,
+ new_name->str, "", flags & FN_TO_IS_TMP);
// Check if we hit FN_REFLEN bytes along with file extension.
if (length+reg_ext_length > FN_REFLEN)
{
@@ -6677,7 +6737,7 @@ remove_key:
DBUG_ASSERT(key->or_replace());
Alter_drop::drop_type type= (key->type == Key::FOREIGN_KEY) ?
Alter_drop::FOREIGN_KEY : Alter_drop::KEY;
- Alter_drop *ad= new Alter_drop(type, key->name.str, FALSE);
+ Alter_drop *ad= new (thd->mem_root) Alter_drop(type, key->name.str, FALSE);
if (ad != NULL)
{
// Adding the index into the drop list for replacing
@@ -7171,9 +7231,8 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
ha_alter_info->handler_flags|= ALTER_STORED_COLUMN_TYPE;
}
- /* Check if field was renamed */
- if (lex_string_cmp(system_charset_info, &field->field_name,
- &new_field->field_name))
+ /* Check if field was renamed (case-sensitive for detecting case change) */
+ if (cmp(&field->field_name, &new_field->field_name))
{
field->flags|= FIELD_IS_RENAMED;
ha_alter_info->handler_flags|= ALTER_COLUMN_NAME;
@@ -8823,8 +8882,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key_part_length= 0; // Use whole field
}
key_part_length /= kfield->charset()->mbmaxlen;
- key_parts.push_back(new (thd->mem_root) Key_part_spec(
- &cfield->field_name, key_part_length),
+ key_parts.push_back(new (thd->mem_root) Key_part_spec(&cfield->field_name,
+ key_part_length, true),
thd->mem_root);
}
if (table->s->tmp_table == NO_TMP_TABLE)
@@ -9709,6 +9768,22 @@ static int create_table_for_inplace_alter(THD *thd,
}
+/*
+ log query if slave thread and send my_ok()
+
+ Help function for mysql_alter_table()
+*/
+
+static bool log_and_ok(THD *thd)
+{
+ if (thd->slave_thread &&
+ write_bin_log(thd, true, thd->query(), thd->query_length()))
+ return(true);
+ my_ok(thd);
+ return(0);
+}
+
+
/**
Alter table
@@ -9778,7 +9853,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
mysql_prepare_create_table().
*/
bool varchar= create_info->varchar, table_creation_was_logged= 0;
- bool binlog_done= 0, log_if_exists= 0;
+ bool binlog_as_create_select= 0, log_if_exists= 0;
uint tables_opened;
handlerton *new_db_type, *old_db_type;
ha_rows copied=0, deleted=0;
@@ -9843,10 +9918,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
table_list->mdl_request.type= MDL_EXCLUSIVE;
/* This will only drop the .frm file and local tables, not shared ones */
error= mysql_rm_table(thd, table_list, 1, 0, 0, 1);
- if (write_bin_log(thd, true, thd->query(), thd->query_length()) || error)
- DBUG_RETURN(true);
- my_ok(thd);
- DBUG_RETURN(0);
+ DBUG_RETURN(log_and_ok(thd));
}
/*
@@ -9878,16 +9950,14 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
the statement as this slave may not have the table shared
*/
thd->clear_error();
- if (thd->slave_thread &&
- write_bin_log(thd, true, thd->query(), thd->query_length()))
- DBUG_RETURN(true);
- my_ok(thd);
- DBUG_RETURN(0);
+ DBUG_RETURN(log_and_ok(thd));
}
}
DBUG_RETURN(true);
}
+ table= table_list->table;
+
#ifdef WITH_WSREP
if (WSREP(thd) &&
(thd->lex->sql_command == SQLCOM_ALTER_TABLE ||
@@ -9899,7 +9969,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
DEBUG_SYNC(thd, "alter_table_after_open_tables");
- table= table_list->table;
if (table->versioned())
{
if (handlerton *hton1= create_info->db_type)
@@ -9938,12 +10007,17 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
Alter_table_ctx alter_ctx(thd, table_list, tables_opened, new_db, new_name);
mdl_ticket= table->mdl_ticket;
+ /*
+ We have to do a check also after table is opened as there could be no
+ ENGINE= on the command line or the table could a partitioned S3 table.
+ */
if (table->file->check_if_updates_are_ignored("ALTER"))
{
/*
Table is a shared table. Remove the .frm file. Discovery will create
a new one if needed.
*/
+ table->s->tdc->flushed= 1; // Force close of all instances
if (thd->mdl_context.upgrade_shared_lock(mdl_ticket,
MDL_EXCLUSIVE,
thd->variables.lock_wait_timeout))
@@ -10700,7 +10774,6 @@ do_continue:;
thd->variables.option_bits|= OPTION_BIN_COMMIT_OFF;
res= (binlog_drop_table(thd, table) ||
binlog_create_table(thd, new_table, 1));
- thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
new_table->s->tmp_table= org_tmp_table;
if (res)
goto err_new_table_cleanup;
@@ -10708,7 +10781,7 @@ do_continue:;
ha_write_row() will log inserted rows in copy_data_between_tables().
No additional logging of query is needed
*/
- binlog_done= 1;
+ binlog_as_create_select= 1;
DBUG_ASSERT(new_table->file->row_logging);
new_table->mark_columns_needed_for_insert();
thd->binlog_write_table_map(new_table, 1);
@@ -10764,10 +10837,21 @@ do_continue:;
if (thd->rename_temporary_table(new_table, &alter_ctx.new_db,
&alter_ctx.new_name))
goto err_new_table_cleanup;
+
+ if (binlog_as_create_select)
+ {
+ /*
+ The original table is now deleted. Copy the
+ DROP + CREATE + data statement to the binary log
+ */
+ thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
+ (binlog_hton->commit)(binlog_hton, thd, 1);
+ }
+
/* We don't replicate alter table statement on temporary tables */
if (!thd->is_current_stmt_binlog_format_row() &&
table_creation_was_logged &&
- !binlog_done &&
+ !binlog_as_create_select &&
write_bin_log_with_if_exists(thd, true, false, log_if_exists))
DBUG_RETURN(true);
my_free(const_cast<uchar*>(frm.str));
@@ -10927,6 +11011,15 @@ do_continue:;
NO_FRM_RENAME |
(engine_changed ? 0 : FN_IS_TMP));
}
+ if (binlog_as_create_select)
+ {
+ /*
+ The original table is now deleted. Copy the
+ DROP + CREATE + data statement to the binary log
+ */
+ thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
+ binlog_hton->commit(binlog_hton, thd, 1);
+ }
if (error)
{
@@ -10939,6 +11032,7 @@ do_continue:;
}
end_inplace:
+ thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
if (thd->locked_tables_list.reopen_tables(thd, false))
goto err_with_mdl_after_alter;
@@ -10950,7 +11044,7 @@ end_inplace:
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
thd->is_current_stmt_binlog_format_row() &&
(create_info->tmp_table())));
- if (!binlog_done)
+ if (!binlog_as_create_select)
{
if (write_bin_log_with_if_exists(thd, true, false, log_if_exists))
DBUG_RETURN(true);
@@ -10968,6 +11062,8 @@ end_inplace:
}
end_temporary:
+ thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
+
my_snprintf(alter_ctx.tmp_buff, sizeof(alter_ctx.tmp_buff),
ER_THD(thd, ER_INSERT_INFO),
(ulong) (copied + deleted), (ulong) deleted,
@@ -10978,6 +11074,8 @@ end_temporary:
err_new_table_cleanup:
DBUG_PRINT("error", ("err_new_table_cleanup"));
+ thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF;
+
my_free(const_cast<uchar*>(frm.str));
/*
No default value was provided for a DATE/DATETIME field, the
@@ -11015,7 +11113,7 @@ err_with_mdl_after_alter:
We can't reset error as we will return 'true' below and the server
expects that error is set
*/
- if (!binlog_done)
+ if (!binlog_as_create_select)
write_bin_log_with_if_exists(thd, FALSE, FALSE, log_if_exists);
err_with_mdl:
@@ -11110,6 +11208,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
bool make_versioned= !from->versioned() && to->versioned();
bool make_unversioned= from->versioned() && !to->versioned();
bool keep_versioned= from->versioned() && to->versioned();
+ bool bulk_insert_started= 0;
Field *to_row_start= NULL, *to_row_end= NULL, *from_row_end= NULL;
MYSQL_TIME query_start;
DBUG_ENTER("copy_data_between_tables");
@@ -11148,6 +11247,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
to->file->extra(HA_EXTRA_PREPARE_FOR_ALTER_TABLE);
to->file->ha_start_bulk_insert(from->file->stats.records,
ignore ? 0 : HA_CREATE_UNIQUE_INDEX_BY_SORT);
+ bulk_insert_started= 1;
mysql_stage_set_work_estimated(thd->m_stage_progress_psi, from->file->stats.records);
List_iterator<Create_field> it(create);
@@ -11416,6 +11516,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
to->file->print_error(my_errno,MYF(0));
error= 1;
}
+ bulk_insert_started= 0;
if (!ignore)
to->file->extra(HA_EXTRA_END_ALTER_COPY);
@@ -11429,7 +11530,10 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
error= 1;
err:
- /* Free resources */
+ if (bulk_insert_started)
+ (void) to->file->ha_end_bulk_insert();
+
+/* Free resources */
if (init_read_record_done)
end_read_record(&info);
delete [] copy;
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 677e6cfa510..9417ec667ff 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1826,7 +1826,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
TABLE table;
char path[FN_REFLEN];
bool result= 0;
- DBUG_ENTER("Triggers::drop_all_triggers");
+ DBUG_ENTER("Table_triggers_list::drop_all_triggers");
table.reset();
init_sql_alloc(key_memory_Table_trigger_dispatcher,
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 22375d2962c..00b9c71cc37 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -2655,8 +2655,7 @@ Field *Type_handler_set::make_conversion_table_field(MEM_ROOT *root,
Field *Type_handler_enum::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
const Typelib *typelib= def.typelib();
@@ -3861,8 +3860,7 @@ Field *Type_handler_set::make_table_field(MEM_ROOT *root,
Field *Type_handler_float::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -3876,8 +3874,7 @@ Field *Type_handler_float::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_double::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -3892,8 +3889,7 @@ Field *Type_handler_double::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_decimal_result::make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
uint dec= def.decimal_scale();
@@ -3909,28 +3905,20 @@ Field *Type_handler_decimal_result::make_schema_field(MEM_ROOT *root,
Field *Type_handler_blob_common::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
- if (show_field)
- {
- return new (root)
- Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(),
- Field::NONE, &name, table->s,
- length_bytes(),
- &my_charset_bin);
- }
- else
- return new (root)
- Field_null(addr.ptr(), 0, Field::NONE, &name, &my_charset_bin);
+ return new (root)
+ Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(),
+ Field::NONE, &name, table->s,
+ length_bytes(),
+ &my_charset_bin);
}
Field *Type_handler_varchar::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
DBUG_ASSERT(def.char_length());
LEX_CSTRING name= def.name();
@@ -3944,7 +3932,7 @@ Field *Type_handler_varchar::make_schema_field(MEM_ROOT *root, TABLE *table,
field->field_length= octet_length;
return field;
}
- else if (show_field)
+ else
{
return new (root)
Field_varstring(addr.ptr(), octet_length,
@@ -3953,16 +3941,12 @@ Field *Type_handler_varchar::make_schema_field(MEM_ROOT *root, TABLE *table,
Field::NONE, &name,
table->s, system_charset_info);
}
- else
- return new (root)
- Field_null(addr.ptr(), 0, Field::NONE, &name, system_charset_info);
}
Field *Type_handler_tiny::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -3974,8 +3958,7 @@ Field *Type_handler_tiny::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_short::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -3987,8 +3970,7 @@ Field *Type_handler_short::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_long::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -4000,8 +3982,7 @@ Field *Type_handler_long::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_longlong::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -4013,8 +3994,7 @@ Field *Type_handler_longlong::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_date_common::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root)
@@ -4025,8 +4005,7 @@ Field *Type_handler_date_common::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_time_common::make_schema_field(MEM_ROOT *root, TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new_Field_time(root,
@@ -4038,8 +4017,7 @@ Field *Type_handler_time_common::make_schema_field(MEM_ROOT *root, TABLE *table,
Field *Type_handler_datetime_common::make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
LEX_CSTRING name= def.name();
return new (root) Field_datetimef(addr.ptr(),
@@ -5703,10 +5681,12 @@ cmp_item *Type_handler_timestamp_common::make_cmp_item(THD *thd,
/***************************************************************************/
-static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
+static int srtcmp_in(const void *cs_, const void *x_, const void *y_)
{
- return cs->strnncollsp(x->ptr(), x->length(),
- y->ptr(), y->length());
+ const CHARSET_INFO *cs= static_cast<const CHARSET_INFO *>(cs_);
+ const String *x= static_cast<const String *>(x_);
+ const String *y= static_cast<const String *>(y_);
+ return cs->strnncollsp(x->ptr(), x->length(), y->ptr(), y->length());
}
in_vector *Type_handler_string_result::make_in_vector(THD *thd,
@@ -6956,6 +6936,24 @@ bool Type_handler_string_result::
/***************************************************************************/
+const Vers_type_handler* Type_handler_temporal_result::vers() const
+{
+ return &vers_type_timestamp;
+}
+
+const Vers_type_handler* Type_handler_string_result::vers() const
+{
+ return &vers_type_timestamp;
+}
+
+const Vers_type_handler* Type_handler_blob_common::vers() const
+
+{
+ return &vers_type_timestamp;
+}
+
+/***************************************************************************/
+
uint Type_handler::Item_time_precision(THD *thd, Item *item) const
{
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 41e840d9ed7..db4f67e343f 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -374,7 +374,7 @@ class Dec_ptr_and_buffer: public Dec_ptr
protected:
my_decimal m_buffer;
public:
- int round_to(my_decimal *to, uint scale, decimal_round_mode mode)
+ int round_to(my_decimal *to, int scale, decimal_round_mode mode)
{
DBUG_ASSERT(m_ptr);
return m_ptr->round_to(to, scale, mode);
@@ -383,6 +383,14 @@ public:
{
return round_to(&m_buffer, scale, mode);
}
+ int round_self_if_needed(int scale, decimal_round_mode mode)
+ {
+ if (scale >= m_ptr->frac)
+ return E_DEC_OK;
+ int res= m_ptr->round_to(&m_buffer, scale, mode);
+ m_ptr= &m_buffer;
+ return res;
+ }
String *to_string_round(String *to, uint dec)
{
/*
@@ -3934,8 +3942,7 @@ public:
virtual Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const
+ const ST_FIELD_INFO &def) const
{
DBUG_ASSERT(0);
return NULL;
@@ -3980,7 +3987,6 @@ public:
SORT_FIELD_ATTR *attr) const= 0;
virtual bool is_packable() const { return false; }
-
virtual uint32 max_display_length(const Item *item) const= 0;
virtual uint32 Item_decimal_notation_int_digits(const Item *item) const { return 0; }
virtual uint32 calc_pack_length(uint32 length) const= 0;
@@ -4817,8 +4823,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *)
const override;
void make_sort_key_part(uchar *to, Item *item,
@@ -5249,7 +5254,7 @@ public:
bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const override;
bool Item_func_div_fix_length_and_dec(Item_func_div *) const override;
bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const override;
- const Vers_type_handler *vers() const override { return &vers_type_timestamp; }
+ const Vers_type_handler *vers() const override;
};
@@ -5286,7 +5291,7 @@ public:
void sort_length(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const override;
- bool is_packable()const override { return true; }
+ bool is_packable() const override { return true; }
bool union_element_finalize(const Item * item) const override;
uint calc_key_length(const Column_definition &def) const override;
bool Column_definition_prepare_stage1(THD *thd,
@@ -5416,7 +5421,7 @@ public:
bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const override;
bool Item_func_div_fix_length_and_dec(Item_func_div *) const override;
bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const override;
- const Vers_type_handler *vers() const override { return &vers_type_timestamp; }
+ const Vers_type_handler *vers() const override;
};
@@ -5477,8 +5482,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5529,8 +5533,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5581,8 +5584,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5648,8 +5650,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5879,8 +5880,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5935,8 +5935,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -5991,8 +5990,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Item_literal *create_literal_item(THD *thd, const char *str, size_t length,
CHARSET_INFO *cs, bool send_error)
const override;
@@ -6202,8 +6200,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Item_literal *create_literal_item(THD *thd, const char *str, size_t length,
CHARSET_INFO *cs, bool send_error)
const override;
@@ -6333,8 +6330,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Item *create_typecast_item(THD *thd, Item *item,
const Type_cast_attributes &attr) const override;
bool validate_implicit_default_value(THD *thd, const Column_definition &def)
@@ -6909,8 +6905,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -7030,8 +7025,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
Field *make_table_field_from_def(TABLE_SHARE *share,
MEM_ROOT *mem_root,
const LEX_CSTRING *name,
@@ -7039,7 +7033,7 @@ public:
const Bit_addr &bit,
const Column_definition_attributes *attr,
uint32 flags) const override;
- const Vers_type_handler *vers() const override { return &vers_type_timestamp; }
+ const Vers_type_handler *vers() const override;
};
@@ -7214,8 +7208,7 @@ public:
Field *make_schema_field(MEM_ROOT *root,
TABLE *table,
const Record_addr &addr,
- const ST_FIELD_INFO &def,
- bool show_field) const override;
+ const ST_FIELD_INFO &def) const override;
};
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 5df9e7dd47d..07dd3b1f6ca 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -58,6 +58,8 @@ static udf_func *add_udf(LEX_CSTRING *name, Item_result ret,
const char *dl, Item_udftype typ);
static void del_udf(udf_func *udf);
static void *find_udf_dl(const char *dl);
+static bool find_udf_everywhere(THD* thd, const LEX_CSTRING &name,
+ TABLE *table);
static const char *init_syms(udf_func *tmp, char *nm)
{
@@ -430,6 +432,41 @@ static udf_func *add_udf(LEX_CSTRING *name, Item_result ret, const char *dl,
return tmp;
}
+/**
+ Find record with the udf in the udf func table
+
+ @param exact_name udf name
+ @param table table of mysql.func
+
+ @retval TRUE found
+ @retral FALSE not found
+*/
+
+static bool find_udf_in_table(const LEX_CSTRING &exact_name, TABLE *table)
+{
+ table->use_all_columns();
+ table->field[0]->store(exact_name.str, exact_name.length, &my_charset_bin);
+ return (!table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar*) table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT));
+}
+
+static bool remove_udf_in_table(const LEX_CSTRING &exact_name, TABLE *table)
+{
+ if (find_udf_in_table(exact_name, table))
+ {
+ int error;
+ if ((error= table->file->ha_delete_row(table->record[0])))
+ {
+ table->file->print_error(error, MYF(0));
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
/*
Drop user defined function.
@@ -446,8 +483,7 @@ static int mysql_drop_function_internal(THD *thd, udf_func *udf, TABLE *table)
{
DBUG_ENTER("mysql_drop_function_internal");
- const char *exact_name_str= udf->name.str;
- size_t exact_name_len= udf->name.length;
+ const LEX_CSTRING exact_name= udf->name;
del_udf(udf);
/*
@@ -460,18 +496,17 @@ static int mysql_drop_function_internal(THD *thd, udf_func *udf, TABLE *table)
if (!table)
DBUG_RETURN(1);
- table->use_all_columns();
- table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin);
- if (!table->file->ha_index_read_idx_map(table->record[0], 0,
- (uchar*) table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
- {
- int error;
- if (unlikely((error= table->file->ha_delete_row(table->record[0]))))
- table->file->print_error(error, MYF(0));
- }
- DBUG_RETURN(0);
+ bool ret= remove_udf_in_table(exact_name, table);
+ DBUG_RETURN(ret);
+}
+
+
+static TABLE *open_udf_func_table(THD *thd)
+{
+ TABLE_LIST tables;
+ tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_FUNC_NAME,
+ &MYSQL_FUNC_NAME, TL_WRITE);
+ return open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
}
@@ -518,8 +553,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (check_ident_length(&udf->name))
DBUG_RETURN(1);
- tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_FUNC_NAME, 0, TL_WRITE);
- table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
+ table= open_udf_func_table(thd);
mysql_rwlock_wrlock(&THR_LOCK_udf);
DEBUG_SYNC(current_thd, "mysql_create_function_after_lock");
@@ -620,42 +654,65 @@ err:
}
-int mysql_drop_function(THD *thd, const LEX_CSTRING *udf_name)
+enum drop_udf_result mysql_drop_function(THD *thd, const LEX_CSTRING *udf_name)
{
TABLE *table;
- TABLE_LIST tables;
udf_func *udf;
DBUG_ENTER("mysql_drop_function");
+ if (thd->locked_tables_mode)
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ DBUG_RETURN(UDF_DEL_RESULT_ERROR);
+ }
+
+ if (!(table= open_udf_func_table(thd)))
+ DBUG_RETURN(UDF_DEL_RESULT_ERROR);
+
+ // Fast pre-check
+ if (!mysql_rwlock_tryrdlock(&THR_LOCK_udf))
+ {
+ bool found= find_udf_everywhere(thd, *udf_name, table);
+ mysql_rwlock_unlock(&THR_LOCK_udf);
+ if (!found)
+ {
+ close_mysql_tables(thd);
+ DBUG_RETURN(UDF_DEL_RESULT_ABSENT);
+ }
+ }
+
if (!initialized)
{
+ close_mysql_tables(thd);
if (opt_noacl)
- my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str);
- else
- my_message(ER_OUT_OF_RESOURCES, ER_THD(thd, ER_OUT_OF_RESOURCES),
- MYF(0));
- DBUG_RETURN(1);
- }
+ DBUG_RETURN(UDF_DEL_RESULT_ABSENT); // SP should be checked
- tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_FUNC_NAME, 0, TL_WRITE);
- table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT);
+ my_message(ER_OUT_OF_RESOURCES, ER_THD(thd, ER_OUT_OF_RESOURCES), MYF(0));
+ DBUG_RETURN(UDF_DEL_RESULT_ERROR);
+ }
mysql_rwlock_wrlock(&THR_LOCK_udf);
+
+ // re-check under protection
+ if (!find_udf_everywhere(thd, *udf_name, table))
+ {
+ close_mysql_tables(thd);
+ mysql_rwlock_unlock(&THR_LOCK_udf);
+ DBUG_RETURN(UDF_DEL_RESULT_ABSENT);
+ }
+
+ if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 0))
+ goto err;
+
+
DEBUG_SYNC(current_thd, "mysql_drop_function_after_lock");
+
if (!(udf= (udf_func*) my_hash_search(&udf_hash, (uchar*) udf_name->str,
(uint) udf_name->length)) )
{
- if (thd->lex->check_exists)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_FUNCTION_NOT_DEFINED,
- ER_THD(thd, ER_FUNCTION_NOT_DEFINED),
- udf_name->str);
- goto done;
- }
-
- my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str);
- goto err;
+ if (remove_udf_in_table(*udf_name, table))
+ goto err;
+ goto done;
}
if (mysql_drop_function_internal(thd, udf, table))
@@ -669,13 +726,24 @@ done:
while binlogging, to avoid binlog inconsistency.
*/
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
- DBUG_RETURN(1);
+ DBUG_RETURN(UDF_DEL_RESULT_ERROR);
- DBUG_RETURN(0);
+ close_mysql_tables(thd);
+ DBUG_RETURN(UDF_DEL_RESULT_DELETED);
err:
+ close_mysql_tables(thd);
mysql_rwlock_unlock(&THR_LOCK_udf);
- DBUG_RETURN(1);
+ DBUG_RETURN(UDF_DEL_RESULT_ERROR);
+}
+
+static bool find_udf_everywhere(THD* thd, const LEX_CSTRING &name,
+ TABLE *table)
+{
+ if (initialized && my_hash_search(&udf_hash, (uchar*) name.str, name.length))
+ return true;
+
+ return find_udf_in_table(name, table);
}
#endif /* HAVE_DLOPEN */
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index ac58a176fed..cb1954353fa 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -155,7 +155,13 @@ void udf_init(void),udf_free(void);
udf_func *find_udf(const char *name, size_t size, bool mark_used=0);
void free_udf(udf_func *udf);
int mysql_create_function(THD *thd,udf_func *udf);
-int mysql_drop_function(THD *thd, const LEX_CSTRING *name);
+enum drop_udf_result
+{
+ UDF_DEL_RESULT_ABSENT,
+ UDF_DEL_RESULT_DELETED,
+ UDF_DEL_RESULT_ERROR
+};
+enum drop_udf_result mysql_drop_function(THD *thd, const LEX_CSTRING *name);
#else
static inline void udf_init(void) { }
static inline void udf_free(void) { }
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index fccc2a426c4..9e6a1cd3bb4 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -189,6 +189,13 @@ static bool check_fields(THD *thd, TABLE_LIST *table, List<Item> &items,
my_error(ER_IT_IS_A_VIEW, MYF(0), table->table_name.str);
return TRUE;
}
+ if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "updating and querying the same temporal periods table");
+
+ return true;
+ }
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_UPDATE);
for (List_iterator_fast<Item> it(items); (item=it++);)
{
@@ -419,6 +426,14 @@ int mysql_update(THD *thd,
DBUG_PRINT("info", ("Switch to multi-update"));
/* pass counter value */
thd->lex->table_count= table_count;
+ if (thd->lex->period_conditions.is_set())
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "updating and querying the same temporal periods table");
+
+ DBUG_RETURN(1);
+ }
+
/* convert to multiupdate */
DBUG_RETURN(2);
}
@@ -542,6 +557,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);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e54b335e418..1b37896f18b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2020, MariaDB Corporation.
+ 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
@@ -115,6 +115,14 @@ int yylex(void *yylval, void *yythd);
#endif
+static Item* escape(THD *thd)
+{
+ thd->lex->escape_used= false;
+ const char *esc= thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES ? "" : "\\";
+ return new (thd->mem_root) Item_string_ascii(thd, esc, MY_TEST(esc[0]));
+}
+
+
/**
@brief Bison callback to report a syntax/OOM error
@@ -325,16 +333,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- We should not introduce new conflicts any more.
+ We should not introduce any further shift/reduce conflicts.
*/
/* Start SQL_MODE_DEFAULT_SPECIFIC */
-%expect 37
+%expect 53
/* End SQL_MODE_DEFAULT_SPECIFIC */
/* Start SQL_MODE_ORACLE_SPECIFIC
-%expect 40
+%expect 56
End SQL_MODE_ORACLE_SPECIFIC */
@@ -1142,16 +1150,6 @@ End SQL_MODE_ORACLE_SPECIFIC */
%token <kwd> XML_SYM
%token <kwd> YEAR_SYM /* SQL-2003-R */
-
-/*
- Give ESCAPE (in LIKE) a very low precedence.
- This allows the concatenation operator || to be used on the right
- side of "LIKE" with sql_mode=PIPES_AS_CONCAT (without ORACLE):
- SELECT 'ab' LIKE 'a'||'b'||'c';
-*/
-%left PREC_BELOW_ESCAPE
-%left ESCAPE_SYM
-
/* A dummy token to force the priority of table_ref production in a join. */
%left CONDITIONLESS_JOIN
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT ON_SYM USING
@@ -1162,10 +1160,12 @@ End SQL_MODE_ORACLE_SPECIFIC */
%left AND_SYM AND_AND_SYM
%left PREC_BELOW_NOT
-%left NOT_SYM
-%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
-%left '=' EQUAL_SYM GE '>' LE '<' NE IS LIKE SOUNDS_SYM REGEXP IN_SYM
+%nonassoc NOT_SYM
+%left '=' EQUAL_SYM GE '>' LE '<' NE
+%nonassoc IS
+%right BETWEEN_SYM
+%left LIKE SOUNDS_SYM REGEXP IN_SYM
%left '|'
%left '&'
%left SHIFT_LEFT SHIFT_RIGHT
@@ -1173,9 +1173,9 @@ End SQL_MODE_ORACLE_SPECIFIC */
%left '*' '/' '%' DIV_SYM MOD_SYM
%left '^'
%left MYSQL_CONCAT_SYM
-%left NEG '~' NOT2_SYM BINARY
-%left COLLATE_SYM
-%left SUBQUERY_AS_EXPR
+%nonassoc NEG '~' NOT2_SYM BINARY
+%nonassoc COLLATE_SYM
+%nonassoc SUBQUERY_AS_EXPR
/*
Tokens that can change their meaning from identifier to something else
@@ -1448,7 +1448,6 @@ End SQL_MODE_ORACLE_SPECIFIC */
select_sublist_qualified_asterisk
expr_or_default set_expr_or_default
signed_literal expr_or_literal
- opt_escape
sp_opt_default
simple_ident_nospvar
field_or_var limit_option
@@ -7757,6 +7756,8 @@ alter_list_item:
}
| ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
{
+ if (check_expression($7, &$4, VCOL_DEFAULT))
+ MYSQL_YYABORT;
if (unlikely(Lex->add_alter_list($4, $7, $3)))
MYSQL_YYABORT;
}
@@ -9299,59 +9300,59 @@ expr:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS TRUE_SYM %prec IS
+ | expr IS TRUE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_istrue(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS not TRUE_SYM %prec IS
+ | expr IS not TRUE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnottrue(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS FALSE_SYM %prec IS
+ | expr IS FALSE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isfalse(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS not FALSE_SYM %prec IS
+ | expr IS not FALSE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotfalse(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS UNKNOWN_SYM %prec IS
+ | expr IS UNKNOWN_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS not UNKNOWN_SYM %prec IS
+ | expr IS not UNKNOWN_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri %prec PREC_BELOW_NOT
- ;
-
-bool_pri:
- bool_pri IS NULL_SYM %prec IS
+ | expr IS NULL_SYM %prec PREC_BELOW_NOT
{
$$= new (thd->mem_root) Item_func_isnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri IS not NULL_SYM %prec IS
+ | expr IS not NULL_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
+ | bool_pri
+ ;
+
+bool_pri:
+ bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
{
$$= new (thd->mem_root) Item_func_equal(thd, $1, $3);
if (unlikely($$ == NULL))
@@ -9373,42 +9374,42 @@ bool_pri:
;
predicate:
- bit_expr IN_SYM subquery
+ predicate IN_SYM subquery
{
$$= new (thd->mem_root) Item_in_subselect(thd, $1, $3);
- if (unlikely($$ == NULL))
+ if (unlikely(!$$))
MYSQL_YYABORT;
}
- | bit_expr not IN_SYM subquery
+ | predicate not IN_SYM subquery
{
Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $4);
- if (unlikely(item == NULL))
+ if (unlikely(!item))
MYSQL_YYABORT;
$$= negate_expression(thd, item);
- if (unlikely($$ == NULL))
+ if (unlikely(!$$))
MYSQL_YYABORT;
}
- | bit_expr IN_SYM '(' expr ')'
+ | predicate IN_SYM '(' expr ')'
{
$$= handle_sql2003_note184_exception(thd, $1, true, $4);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr IN_SYM '(' expr ',' expr_list ')'
- {
+ | predicate IN_SYM '(' expr ',' expr_list ')'
+ {
$6->push_front($4, thd->mem_root);
$6->push_front($1, thd->mem_root);
$$= new (thd->mem_root) Item_func_in(thd, *$6);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr not IN_SYM '(' expr ')'
+ | predicate not IN_SYM '(' expr ')'
{
$$= handle_sql2003_note184_exception(thd, $1, false, $5);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr not IN_SYM '(' expr ',' expr_list ')'
+ | predicate not IN_SYM '(' expr ',' expr_list ')'
{
$7->push_front($5, thd->mem_root);
$7->push_front($1, thd->mem_root);
@@ -9417,13 +9418,13 @@ predicate:
MYSQL_YYABORT;
$$= item->neg_transformer(thd);
}
- | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
+ | predicate BETWEEN_SYM predicate AND_SYM predicate %prec BETWEEN_SYM
{
$$= new (thd->mem_root) Item_func_between(thd, $1, $3, $5);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
+ | predicate not BETWEEN_SYM predicate AND_SYM predicate %prec BETWEEN_SYM
{
Item_func_between *item;
item= new (thd->mem_root) Item_func_between(thd, $1, $4, $6);
@@ -9431,7 +9432,7 @@ predicate:
MYSQL_YYABORT;
$$= item->neg_transformer(thd);
}
- | bit_expr SOUNDS_SYM LIKE bit_expr
+ | predicate SOUNDS_SYM LIKE predicate
{
Item *item1= new (thd->mem_root) Item_func_soundex(thd, $1);
Item *item4= new (thd->mem_root) Item_func_soundex(thd, $4);
@@ -9441,28 +9442,41 @@ predicate:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr LIKE bit_expr opt_escape
+ | predicate LIKE predicate
{
- $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4,
- Lex->escape_used);
- if (unlikely($$ == NULL))
+ $$= new (thd->mem_root) Item_func_like(thd, $1, $3, escape(thd), false);
+ if (unlikely(!$$))
MYSQL_YYABORT;
}
- | bit_expr not LIKE bit_expr opt_escape
+ | predicate LIKE predicate ESCAPE_SYM predicate %prec LIKE
{
- Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5,
- Lex->escape_used);
- if (unlikely(item == NULL))
+ Lex->escape_used= true;
+ $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $5, true);
+ if (unlikely(!$$))
+ MYSQL_YYABORT;
+ }
+ | predicate not LIKE predicate
+ {
+ Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, escape(thd), false);
+ if (unlikely(!item))
MYSQL_YYABORT;
$$= item->neg_transformer(thd);
}
- | bit_expr REGEXP bit_expr
+ | predicate not LIKE predicate ESCAPE_SYM predicate %prec LIKE
+ {
+ Lex->escape_used= true;
+ Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $6, true);
+ if (unlikely(!item))
+ MYSQL_YYABORT;
+ $$= item->neg_transformer(thd);
+ }
+ | predicate REGEXP predicate
{
$$= new (thd->mem_root) Item_func_regex(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | bit_expr not REGEXP bit_expr
+ | predicate not REGEXP predicate
{
Item *item= new (thd->mem_root) Item_func_regex(thd, $1, $4);
if (unlikely(item == NULL))
@@ -10592,18 +10606,19 @@ function_call_generic:
names are resolved with the following order:
- MySQL native functions,
- User Defined Functions,
+ - Constructors, like POINT(1,1)
- Stored Functions (assuming the current <use> database)
This will be revised with WL#2128 (SQL PATH)
*/
- if ((h= Type_handler::handler_by_name(thd, $1)) &&
- (item= h->make_constructor_item(thd, $4)))
+ if ((builder= find_native_function_builder(thd, &$1)))
{
- // Found a constructor with a proper argument count
+ item= builder->create_func(thd, &$1, $4);
}
- else if ((builder= find_native_function_builder(thd, &$1)))
+ else if ((h= Type_handler::handler_by_name(thd, $1)) &&
+ (item= h->make_constructor_item(thd, $4)))
{
- item= builder->create_func(thd, &$1, $4);
+ // Found a constructor with a proper argument count
}
else
{
@@ -11904,23 +11919,6 @@ opt_having_clause:
}
;
-opt_escape:
- ESCAPE_SYM simple_expr
- {
- Lex->escape_used= TRUE;
- $$= $2;
- }
- | /* empty */ %prec PREC_BELOW_ESCAPE
- {
- Lex->escape_used= FALSE;
- $$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ?
- new (thd->mem_root) Item_string_ascii(thd, "", 0) :
- new (thd->mem_root) Item_string_ascii(thd, "\\", 1));
- if (unlikely($$ == NULL))
- MYSQL_YYABORT;
- }
- ;
-
/*
group by statement in select
*/
@@ -14181,6 +14179,8 @@ backup_statements:
}
| LOCK_SYM
{
+ if (unlikely(Lex->sphead))
+ my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "BACKUP LOCK"));
if (Lex->main_select_push())
MYSQL_YYABORT;
}
@@ -14194,6 +14194,8 @@ backup_statements:
}
| UNLOCK_SYM
{
+ if (unlikely(Lex->sphead))
+ my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "BACKUP UNLOCK"));
/* Table list is empty for unlock */
Lex->sql_command= SQLCOM_BACKUP_LOCK;
}
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index c21a4a83165..2bd6ee6467d 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -769,8 +769,12 @@ public:
void session_save_default(THD *, set_var *) override
{ DBUG_ASSERT(FALSE); }
- void global_save_default(THD *, set_var *) override
- { DBUG_ASSERT(FALSE); }
+ void global_save_default(THD *thd, set_var *var) override
+ {
+ 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 *, set_var *) override
{
diff --git a/sql/table.cc b/sql/table.cc
index 779ce768eee..c48a6fed89a 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2367,7 +2367,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
comment_pos+= comment_length;
}
- if ((uchar) strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL)
+ if ((uchar) strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL
+ && likely(share->mysql_version >= 100000))
{
/*
MariaDB version 10.0 version.
@@ -2417,7 +2418,18 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
interval_nr= (uint) strpos[12];
enum_field_types field_type= (enum_field_types) strpos[13];
if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
- goto err; // Not supported field type
+ {
+ if (field_type == 245 &&
+ share->mysql_version >= 50700) // a.k.a MySQL 5.7 JSON
+ {
+ share->incompatible_version|= HA_CREATE_USED_ENGINE;
+ const LEX_CSTRING mysql_json{STRING_WITH_LEN("MYSQL_JSON")};
+ handler= Type_handler::handler_by_name_or_error(thd, mysql_json);
+ }
+
+ if (!handler)
+ goto err; // Not supported field type
+ }
handler= handler->type_handler_frm_unpack(strpos);
if (handler->Column_definition_attributes_frm_unpack(&attr, share,
strpos,
@@ -8498,28 +8510,39 @@ public:
@details
The function computes the values of the virtual columns of the table and
stores them in the table record buffer.
+ This will be done even if is_error() is set either when function was called
+ or by calculating the virtual function, as most calls to this
+ function doesn't check the result. We also want to ensure that as many
+ fields as possible has the right value so that we can optionally
+ return the partly-faulty-row from a storage engine with a virtual
+ field that gives an error on storage for an existing row.
+
+ @todo
+ Ensure that all caller checks the value of this function and
+ either properly ignores it (and resets the error) or sends the
+ error forward to the caller.
@retval
0 Success
@retval
- >0 Error occurred when storing a virtual field value
+ >0 Error occurred when storing a virtual field value or potentially
+ is_error() was set when function was called.
*/
int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
{
DBUG_ENTER("TABLE::update_virtual_fields");
- DBUG_PRINT("enter", ("update_mode: %d", update_mode));
+ DBUG_PRINT("enter", ("update_mode: %d is_error: %d", update_mode,
+ in_use->is_error()));
Field **vfield_ptr, *vf;
Query_arena backup_arena;
Turn_errors_to_warnings_handler Suppress_errors;
- int error;
bool handler_pushed= 0, update_all_columns= 1;
DBUG_ASSERT(vfield);
if (h->keyread_enabled())
DBUG_RETURN(0);
- error= 0;
in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
/* When reading or deleting row, ignore errors from virtual columns */
@@ -8542,7 +8565,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
}
/* Iterate over virtual fields in the table */
- for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
+ for (vfield_ptr= vfield; *vfield_ptr ; vfield_ptr++)
{
vf= (*vfield_ptr);
Virtual_column_info *vcol_info= vf->vcol_info;
@@ -8593,8 +8616,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
int field_error __attribute__((unused)) = 0;
/* Compute the actual value of the virtual fields */
DBUG_FIX_WRITE_SET(vf);
- if (vcol_info->expr->save_in_field(vf, 0))
- field_error= error= 1;
+ field_error= vcol_info->expr->save_in_field(vf, 0);
DBUG_RESTORE_WRITE_SET(vf);
DBUG_PRINT("info", ("field '%s' - updated error: %d",
vf->field_name.str, field_error));
@@ -8719,6 +8741,7 @@ int TABLE::period_make_insert(Item *src, Field *dst)
{
THD *thd= in_use;
+ file->store_auto_increment();
store_record(this, record[1]);
int res= src->save_in_field(dst, true);
@@ -8737,6 +8760,8 @@ int TABLE::period_make_insert(Item *src, Field *dst)
TRG_ACTION_AFTER, true);
restore_record(this, record[1]);
+ if (res)
+ file->restore_auto_increment();
return res;
}
diff --git a/sql/table.h b/sql/table.h
index 63bcc69b6bc..71884c919ad 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2244,7 +2244,6 @@ struct TABLE_LIST
parsing 'this' is a NATURAL/USING join iff (natural_join != NULL).
*/
TABLE_LIST *natural_join;
- bool part_of_natural_join;
/*
True if 'this' represents a nested join that is a NATURAL JOIN.
For one of the operands of 'this', the member 'natural_join' points
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index b26f41c6e9a..168579d984b 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -317,6 +317,16 @@ static void handle_wait_timeout(THD *thd)
thd->net.error= 2;
}
+/** Check if some client data is cached in thd->net or thd->net.vio */
+static bool has_unread_data(THD* thd)
+{
+ NET *net= &thd->net;
+ if (net->compress && net->remain_in_buf)
+ return true;
+ Vio *vio= net->vio;
+ return vio->has_data(vio);
+}
+
/**
Process a single client request or a single batch.
@@ -351,7 +361,6 @@ static int threadpool_process_request(THD *thd)
*/
for(;;)
{
- Vio *vio;
thd->net.reading_or_writing= 0;
if (mysql_audit_release_required(thd))
mysql_audit_release(thd);
@@ -367,8 +376,7 @@ static int threadpool_process_request(THD *thd)
set_thd_idle(thd);
- vio= thd->net.vio;
- if (!vio->has_data(vio))
+ if (!has_unread_data(thd))
{
/* More info on this debug sync is in sql_parse.cc*/
DEBUG_SYNC(thd, "before_do_command_net_read");
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 51c23085717..4461d73a928 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -158,7 +158,8 @@ extern const char* wsrep_provider_vendor;
extern char* wsrep_provider_capabilities;
extern char* wsrep_cluster_capabilities;
-int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff);
+int wsrep_show_status(THD *thd, SHOW_VAR *var, void *buff,
+ system_status_var *status_var, enum_var_type scope);
int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff);
void wsrep_free_status(THD *thd);
void wsrep_update_cluster_state_uuid(const char* str);
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index f8c3f4d299b..25992459060 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1825,6 +1825,35 @@ 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;
+}
+
int wsrep_sst_donate(const std::string& msg,
const wsrep::gtid& current_gtid,
const bool bypass)
@@ -1836,8 +1865,21 @@ int wsrep_sst_donate(const std::string& msg,
const char* method= msg.data();
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;
+ }
+
wsp::env env(NULL);
if (env.error())
{
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 8c9170a3745..97aca456369 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -921,7 +921,8 @@ static void export_wsrep_status_to_mysql(THD* thd)
mysql_status_vars[wsrep_status_len].type = SHOW_LONG;
}
-int wsrep_show_status (THD *thd, SHOW_VAR *var, char *buff)
+int wsrep_show_status (THD *thd, SHOW_VAR *var, void *,
+ system_status_var *, enum_var_type)
{
/* Note that we should allow show status like 'wsrep%' even
when WSREP(thd) is false. */
diff --git a/sql/xa.cc b/sql/xa.cc
index e8e6dc43c56..15833377fb6 100644
--- a/sql/xa.cc
+++ b/sql/xa.cc
@@ -689,7 +689,7 @@ bool trans_xa_commit(THD *thd)
{
DEBUG_SYNC(thd, "trans_xa_commit_after_acquire_commit_lock");
- res= MY_TEST(ha_commit_one_phase(thd, 1, 1));
+ res= MY_TEST(ha_commit_one_phase(thd, 1));
if (res)
my_error(ER_XAER_RMERR, MYF(0));
else
diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h
index c2a36a68f45..baa140bc04a 100644
--- a/storage/blackhole/ha_blackhole.h
+++ b/storage/blackhole/ha_blackhole.h
@@ -20,6 +20,7 @@
#include "thr_lock.h" /* THR_LOCK */
#include "handler.h" /* handler */
#include "table.h" /* TABLE_SHARE */
+#include "sql_const.h" /* MAX_KEY */
/*
Shared structure for correct LOCK operation
@@ -65,9 +66,9 @@ public:
HA_READ_ORDER | HA_KEYREAD_ONLY);
}
/* The following defines can be increased if necessary */
-#define BLACKHOLE_MAX_KEY 64 /* Max allowed keys */
+#define BLACKHOLE_MAX_KEY MAX_KEY /* Max allowed keys */
#define BLACKHOLE_MAX_KEY_SEG 16 /* Max segments for key */
-#define BLACKHOLE_MAX_KEY_LENGTH 1000
+#define BLACKHOLE_MAX_KEY_LENGTH 3500 /* Like in InnoDB */
uint max_supported_keys() const { return BLACKHOLE_MAX_KEY; }
uint max_supported_key_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
uint max_supported_key_part_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore
-Subproject b6b02ed516f92055127d416370799d91a82754e
+Subproject 86347532abf1f7dae8896a96d5b7251233fca22
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index eb14e846120..6cd4bae6999 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -1207,7 +1207,6 @@ int UZDFAM::Cardinality(PGLOBAL g)
return 1;
int card = -1;
- int len = GetFileLength(g);
card = Records;
diff --git a/storage/connect/global.h b/storage/connect/global.h
index fd26c87b800..d17620861fa 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -1,7 +1,7 @@
/***********************************************************************/
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */
/* (C) Copyright MariaDB Corporation Ab */
-/* Author Olivier Bertrand 1993-2018 */
+/* Author Olivier Bertrand 1993-2020 */
/***********************************************************************/
/***********************************************************************/
@@ -89,14 +89,10 @@ extern "C" {
#define PAT_LOG "log"
#if defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
- /*********************************************************************/
- /* printf does not accept null pointer for %s target. */
- /*********************************************************************/
+ // printf does not accept null pointer for %s target
#define SVP(S) ((S) ? S : "<null>")
#else
- /*********************************************************************/
- /* printf accepts null pointer for %s target. */
- /*********************************************************************/
+ // printf accepts null pointer for %s target
#define SVP(S) S
#endif
@@ -112,9 +108,6 @@ extern "C" {
/***********************************************************************/
#include "os.h"
-typedef uint OFFSET;
-typedef char NAME[9];
-
typedef struct {
ushort Length;
char String[2];
@@ -127,6 +120,7 @@ typedef struct _global *PGLOBAL;
typedef struct _globplg *PGS;
typedef struct _activity *PACTIVITY;
typedef struct _parm *PPARM;
+typedef char NAME[9];
/***********************************************************************/
/* Segment Sub-Allocation block structure declares. */
@@ -135,8 +129,8 @@ typedef struct _parm *PPARM;
/* restore them if needed. This scheme implies that no SubFree be used */
/***********************************************************************/
typedef struct { /* Plug Area SubAlloc header */
- OFFSET To_Free; /* Offset of next free block */
- uint FreeBlk; /* Size of remaining free memory */
+ size_t To_Free; /* Offset of next free block */
+ size_t FreeBlk; /* Size of remaining free memory */
} POOLHEADER, *PPOOLHEADER;
/***********************************************************************/
@@ -188,11 +182,12 @@ typedef struct _parm {
/***********************************************************************/
typedef struct _global { /* Global structure */
void *Sarea; /* Points to work area */
- uint Sarea_Size; /* Work area size */
+ size_t Sarea_Size; /* Work area size */
PACTIVITY Activityp;
- char Message[MAX_STR];
+ char Message[MAX_STR]; /* Message (result, error, trace) */
ulong More; /* Used by jsonudf */
- int Createas; /* To pass multi to ext tables */
+ size_t Saved_Size; /* Saved work area to_free */
+ bool Createas; /* To pass multi to ext tables */
void *Xchk; /* indexes in create/alter */
short Alchecked; /* Checked for ALTER */
short Mrr; /* True when doing mrr */
@@ -210,19 +205,18 @@ DllExport char *PlugReadMessage(PGLOBAL, int, char *);
DllExport char *PlugGetMessage(PGLOBAL, int);
#endif // XMSG || NEWMSG
#if defined(__WIN__)
-DllExport short GetLineLength(PGLOBAL); // Console line length
+DllExport short GetLineLength(PGLOBAL); // Console line length
#endif // __WIN__
-DllExport PGLOBAL PlugInit(LPCSTR, uint); // Plug global initialization
-DllExport int PlugExit(PGLOBAL); // Plug global termination
+DllExport PGLOBAL PlugInit(LPCSTR, size_t); // Plug global initialization
+DllExport int PlugExit(PGLOBAL); // Plug global termination
DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR);
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir);
DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
-DllExport bool AllocSarea(PGLOBAL, uint);
+DllExport bool AllocSarea(PGLOBAL, size_t);
DllExport void FreeSarea(PGLOBAL);
-DllExport BOOL PlugSubSet(void *, uint);
+DllExport BOOL PlugSubSet(void *, size_t);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
-DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
DllExport void xtrc(uint, char const* fmt, ...);
DllExport uint GetTraceValue(void);
@@ -232,8 +226,24 @@ DllExport uint GetTraceValue(void);
#endif
/***********************************************************************/
-/* Non exported routine declarations. */
+/* Inline routine definitions. */
+/***********************************************************************/
+/***********************************************************************/
+/* This routine makes a pointer from an offset to a memory pointer. */
+/***********************************************************************/
+inline void* MakePtr(void* memp, size_t offset) {
+ // return ((offset == 0) ? NULL : &((char*)memp)[offset]);
+ return (!offset) ? NULL : (char *)memp + offset;
+} /* end of MakePtr */
+
+/***********************************************************************/
+/* This routine makes an offset from a pointer new format. */
/***********************************************************************/
-//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
+inline size_t MakeOff(void* memp, void* ptr) {
+#if defined(_DEBUG)
+ assert(ptr > memp);
+#endif // _DEBUG
+ return ((!ptr) ? 0 : (size_t)((char*)ptr - (size_t)memp));
+} /* end of MakeOff */
/*-------------------------- End of Global.H --------------------------*/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index a5d000d566d..849cf7594eb 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,9 +170,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.07.0001 November 12, 2019";
+ char version[]= "Version 1.07.0002 October 18, 2020";
#if defined(__WIN__)
- char compver[]= "Version 1.07.0001 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__;
static char slash= '\\';
#else // !__WIN__
static char slash= '/';
@@ -251,11 +251,13 @@ bool ExactInfo(void);
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
+bool JsonAllPath(void);
char *GetJsonNull(void);
+int GetDefaultDepth(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
-uint GetWorkSize(void);
-void SetWorkSize(uint);
+size_t GetWorkSize(void);
+void SetWorkSize(size_t);
extern "C" const char *msglang(void);
static void PopUser(PCONNECT xp);
@@ -345,11 +347,19 @@ static MYSQL_THDVAR_ENUM(
1, // def (AUTO)
&usetemp_typelib); // typelib
+#ifdef _WIN64
// Size used for g->Sarea_Size
-static MYSQL_THDVAR_UINT(work_size,
- PLUGIN_VAR_RQCMDARG,
- "Size of the CONNECT work area.",
- NULL, NULL, SZWORK, SZWMIN, UINT_MAX, 1);
+static MYSQL_THDVAR_ULONGLONG(work_size,
+ PLUGIN_VAR_RQCMDARG,
+ "Size of the CONNECT work area.",
+ NULL, NULL, SZWORK, SZWMIN, ULONGLONG_MAX, 1);
+#else
+// Size used for g->Sarea_Size
+static MYSQL_THDVAR_ULONG(work_size,
+ PLUGIN_VAR_RQCMDARG,
+ "Size of the CONNECT work area.",
+ NULL, NULL, SZWORK, SZWMIN, ULONG_MAX, 1);
+#endif
// Size used when converting TEXT columns to VARCHAR
static MYSQL_THDVAR_INT(conv_size,
@@ -384,6 +394,11 @@ static MYSQL_THDVAR_ENUM(
1, // def (yes)
&xconv_typelib); // typelib
+// Adding JPATH to all Json table columns
+static MYSQL_THDVAR_BOOL(json_all_path, PLUGIN_VAR_RQCMDARG,
+ "Adding JPATH to all Json table columns",
+ NULL, NULL, 0); // NO by default
+
// Null representation for JSON values
static MYSQL_THDVAR_STR(json_null,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
@@ -391,6 +406,12 @@ static MYSQL_THDVAR_STR(json_null,
// check_json_null, update_json_null,
NULL, NULL, "<null>");
+// Default Json, XML or Mongo depth
+static MYSQL_THDVAR_INT(default_depth,
+ PLUGIN_VAR_RQCMDARG,
+ "Default depth used by Json, XML and Mongo discovery",
+ NULL, NULL, 0, -1, 16, 1);
+
// Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size,
PLUGIN_VAR_RQCMDARG, // opt
@@ -452,15 +473,17 @@ uint GetTraceValue(void)
{return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);}
bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
static bool CondPushEnabled(void) {return THDVAR(current_thd, cond_push);}
+bool JsonAllPath(void) {return THDVAR(current_thd, json_all_path);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
char *GetJsonNull(void)
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
+int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);}
uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
-uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
-void SetWorkSize(uint)
+size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);}
+void SetWorkSize(size_t)
{
// Changing the session variable value seems to be impossible here
// and should be done in a check function
@@ -470,7 +493,8 @@ void SetWorkSize(uint)
#if defined(JAVA_SUPPORT)
char *GetJavaWrapper(void)
-{return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";}
+{return connect_hton ? THDVAR(current_thd, java_wrapper)
+ : (char*)"wrappers/JdbcInterface";}
#endif // JAVA_SUPPORT
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
@@ -619,8 +643,10 @@ ha_create_table_option connect_field_option_list[]=
HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1),
HA_FOPTION_STRING("DATE_FORMAT", dateformat),
HA_FOPTION_STRING("FIELD_FORMAT", fieldformat),
- HA_FOPTION_STRING("SPECIAL", special),
- HA_FOPTION_ENUM("DISTRIB", opt, "scattered,clustered,sorted", 0),
+ HA_FOPTION_STRING("JPATH", jsonpath),
+ HA_FOPTION_STRING("XPATH", xmlpath),
+ HA_FOPTION_STRING("SPECIAL", special),
+ HA_FOPTION_ENUM("DISTRIB", opt, "scattered,clustered,sorted", 0),
HA_FOPTION_END
};
@@ -1310,9 +1336,10 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, PCSZ opname, int idef)
if ((ulonglong) opval == (ulonglong)NO_IVAL) {
PCSZ pv;
- if ((pv= GetListOption(g, opname, options->oplist)))
- opval= CharToNumber((char*)pv, strlen(pv), ULONGLONG_MAX, true);
- else
+ if ((pv = GetListOption(g, opname, options->oplist))) {
+ // opval = CharToNumber((char*)pv, strlen(pv), ULONGLONG_MAX, false);
+ return atoi(pv);
+ } else
return idef;
} // endif opval
@@ -1564,8 +1591,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Offset= (int)fop->offset;
pcf->Freq= (int)fop->freq;
pcf->Datefmt= (char*)fop->dateformat;
- pcf->Fieldfmt= (char*)fop->fieldformat;
- } else {
+ pcf->Fieldfmt = fop->fieldformat ? (char*)fop->fieldformat
+ : fop->jsonpath ? (char*)fop->jsonpath : (char*)fop->xmlpath;
+ } else {
pcf->Offset= -1;
pcf->Freq= 0;
pcf->Datefmt= NULL;
@@ -1574,6 +1602,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
chset= (char *)fp->charset()->name;
+ if (!strcmp(chset, "binary"))
+ v = 'B'; // Binary string
+
switch (fp->type()) {
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR:
@@ -1583,7 +1614,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
default:
pcf->Type= MYSQLtoPLG(fp->type(), &v);
break;
- } // endswitch SQL type
+ } // endswitch SQL type
switch (pcf->Type) {
case TYPE_STRING:
@@ -1637,7 +1668,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
break;
default:
break;
- } // endswitch type
+ } // endswitch type
if (fp->flags & UNSIGNED_FLAG)
pcf->Flags |= U_UNSIGNED;
@@ -2208,7 +2239,7 @@ int ha_connect::MakeRecord(char *buf)
case TYPE_BIN:
p= value->GetCharValue();
charset= &my_charset_bin;
- rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
+ rc= fp->store(p, value->GetSize(), charset, CHECK_FIELD_WARN);
break;
case TYPE_DOUBLE:
rc= fp->store(value->GetFloatValue());
@@ -4500,14 +4531,13 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
case TAB_DIR:
case TAB_ZIP:
case TAB_OEM:
- if (table && table->pos_in_table_list) // if SELECT
- {
+ if (table && table->pos_in_table_list) { // if SELECT
#if MYSQL_VERSION_ID > 100200
Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list);
#endif // VERSION_ID > 100200
+
return check_global_access(thd, FILE_ACL);
- }
- else
+ } else
return check_global_access(thd, FILE_ACL);
case TAB_ODBC:
case TAB_JDBC:
@@ -4523,7 +4553,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
case TAB_VIR:
// This is temporary until a solution is found
return false;
- } // endswitch type
+ } // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true;
@@ -4968,7 +4998,7 @@ int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras)
} // endif CheckCleanup
if (cras)
- g->Createas= 1; // To tell external tables of a multi-table command
+ g->Createas= true; // To tell external tables of a multi-table command
if (trace(1))
htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras);
@@ -5322,91 +5352,100 @@ static char *encode(PGLOBAL g, const char *cnm)
@return
Return 0 if ok
*/
-static bool add_field(String *sql, const char *field_name, int typ, int len,
- int dec, char *key, uint tm, const char *rem, char *dft,
- char *xtra, char *fmt, int flag, bool dbf, char v)
-{
- char var= (len > 255) ? 'V' : v;
- bool q, error= false;
- const char *type= PLGtoMYSQLtype(typ, dbf, var);
+static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
+ int len, int dec, char* key, uint tm, const char* rem,
+ char* dft, char* xtra, char* fmt, int flag, bool dbf, char v) {
+#if defined(DEVELOPMENT)
+ // Some client programs regard CHAR(36) as GUID
+ char var = (len > 255 || len == 36) ? 'V' : v;
+#else
+ char var = (len > 255) ? 'V' : v;
+#endif
+ bool q, error = false;
+ const char* type = PLGtoMYSQLtype(typ, dbf, var);
- error|= sql->append('`');
- error|= sql->append(field_name);
- error|= sql->append("` ");
- error|= sql->append(type);
+ error |= sql->append('`');
+ error |= sql->append(field_name);
+ error |= sql->append("` ");
+ error |= sql->append(type);
- if (typ == TYPE_STRING ||
- (len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0))) {
- error|= sql->append('(');
- error|= sql->append_ulonglong(len);
+ if (typ == TYPE_STRING ||
+ (len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0))) {
+ error |= sql->append('(');
+ error |= sql->append_ulonglong(len);
if (typ == TYPE_DOUBLE) {
- error|= sql->append(',');
- // dec must be < len and < 31
- error|= sql->append_ulonglong(MY_MIN(dec, (MY_MIN(len, 31) - 1)));
- } else if (dec > 0 && !strcmp(type, "DECIMAL")) {
- error|= sql->append(',');
- // dec must be < len
- error|= sql->append_ulonglong(MY_MIN(dec, len - 1));
- } // endif dec
-
- error|= sql->append(')');
- } // endif len
-
- if (v == 'U')
- error|= sql->append(" UNSIGNED");
- else if (v == 'Z')
- error|= sql->append(" ZEROFILL");
-
- if (key && *key) {
- error|= sql->append(" ");
- error|= sql->append(key);
- } // endif key
-
- if (tm)
- error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
-
- if (dft && *dft) {
- error|= sql->append(" DEFAULT ");
-
- if (typ == TYPE_DATE)
- q= (strspn(dft, "0123456789 -:/") == strlen(dft));
- else
- q= !IsTypeNum(typ);
+ error |= sql->append(',');
+ // dec must be < len and < 31
+ error |= sql->append_ulonglong(MY_MIN(dec, (MY_MIN(len, 31) - 1)));
+ } else if (dec > 0 && !strcmp(type, "DECIMAL")) {
+ error |= sql->append(',');
+ // dec must be < len
+ error |= sql->append_ulonglong(MY_MIN(dec, len - 1));
+ } // endif dec
+
+ error |= sql->append(')');
+ } // endif len
+
+ if (v == 'U')
+ error |= sql->append(" UNSIGNED");
+ else if (v == 'Z')
+ error |= sql->append(" ZEROFILL");
+
+ if (key && *key) {
+ error |= sql->append(" ");
+ error |= sql->append(key);
+ } // endif key
+
+ if (tm)
+ error |= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
+
+ if (dft && *dft) {
+ error |= sql->append(" DEFAULT ");
+
+ if (typ == TYPE_DATE)
+ q = (strspn(dft, "0123456789 -:/") == strlen(dft));
+ else
+ q = !IsTypeNum(typ);
- if (q) {
- error|= sql->append("'");
- error|= sql->append_for_single_quote(dft, strlen(dft));
- error|= sql->append("'");
- } else
- error|= sql->append(dft);
-
- } // endif dft
-
- if (xtra && *xtra) {
- error|= sql->append(" ");
- error|= sql->append(xtra);
- } // endif rem
-
- if (rem && *rem) {
- error|= sql->append(" COMMENT '");
- error|= sql->append_for_single_quote(rem, strlen(rem));
- error|= sql->append("'");
- } // endif rem
-
- if (fmt && *fmt) {
- error|= sql->append(" FIELD_FORMAT='");
- error|= sql->append_for_single_quote(fmt, strlen(fmt));
- error|= sql->append("'");
- } // endif flag
-
- if (flag) {
- error|= sql->append(" FLAG=");
- error|= sql->append_ulonglong(flag);
- } // endif flag
-
- error|= sql->append(',');
- return error;
+ if (q) {
+ error |= sql->append("'");
+ error |= sql->append_for_single_quote(dft, strlen(dft));
+ error |= sql->append("'");
+ } else
+ error |= sql->append(dft);
+
+ } // endif dft
+
+ if (xtra && *xtra) {
+ error |= sql->append(" ");
+ error |= sql->append(xtra);
+ } // endif rem
+
+ if (rem && *rem) {
+ error |= sql->append(" COMMENT '");
+ error |= sql->append_for_single_quote(rem, strlen(rem));
+ error |= sql->append("'");
+ } // endif rem
+
+ if (fmt && *fmt) {
+ switch (ttp) {
+ case TAB_JSON: error |= sql->append(" JPATH='"); break;
+ case TAB_XML: error |= sql->append(" XPATH='"); break;
+ default: error |= sql->append(" FIELD_FORMAT='");
+ } // endswitch ttp
+
+ error |= sql->append_for_single_quote(fmt, strlen(fmt));
+ error |= sql->append("'");
+ } // endif flag
+
+ if (flag) {
+ error |= sql->append(" FLAG=");
+ error |= sql->append_ulonglong(flag);
+ } // endif flag
+
+ error |= sql->append(',');
+ return error;
} // end of add_field
/**
@@ -6027,7 +6066,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
len= 256; // STRBLK's have 0 length
// Now add the field
- if (add_field(&sql, cnm, typ, len, dec, NULL, tm,
+ if (add_field(&sql, ttp, cnm, typ, len, dec, NULL, tm,
NULL, NULL, NULL, NULL, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
} // endfor crp
@@ -6221,7 +6260,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
prec= 0;
// Now add the field
- if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
+ if (add_field(&sql, ttp, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
fmt, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
} // endfor i
@@ -6974,7 +7013,7 @@ bool ha_connect::NoFieldOptionChange(TABLE *tab)
fop1->fldlen == fop2->fldlen &&
CheckString(fop1->dateformat, fop2->dateformat) &&
CheckString(fop1->fieldformat, fop2->fieldformat) &&
- CheckString(fop1->special, fop2->special));
+ CheckString(fop1->special, fop2->special));
} // endfor fld
return rc;
@@ -7346,7 +7385,9 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
MYSQL_SYSVAR(json_null),
- MYSQL_SYSVAR(json_grp_size),
+ MYSQL_SYSVAR(json_all_path),
+ MYSQL_SYSVAR(default_depth),
+ MYSQL_SYSVAR(json_grp_size),
#if defined(JAVA_SUPPORT)
MYSQL_SYSVAR(jvm_path),
MYSQL_SYSVAR(class_path),
@@ -7372,7 +7413,7 @@ maria_declare_plugin(connect)
0x0107, /* version number (1.07) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.07.0001", /* string version */
+ "1.07.0002", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 8be1fe262b6..d1aca22b01f 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -104,7 +104,9 @@ struct ha_field_option_struct
uint opt;
const char *dateformat;
const char *fieldformat;
- char *special;
+ const char* jsonpath;
+ const char* xmlpath;
+ char *special;
};
/*
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index 5d7d08285cf..f6dca8146d6 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -93,9 +93,8 @@ char *NextChr(PSZ s, char sep)
PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
{
int i, pretty = (ptyp) ? *ptyp : 3;
- bool b = false, pty[3] = {true, true, true};
- PJSON jsp = NULL;
- STRG src;
+ bool b = false, pty[3] = {true,true,true};
+ PJSON jsp = NULL, jp = NULL;
if (trace(1))
htrc("ParseJson: s=%.10s len=%d\n", s, len);
@@ -106,27 +105,29 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
} else if (comma)
*comma = false;
- src.str = s;
- src.len = len;
-
// Trying to guess the pretty format
if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
pty[0] = false;
try {
- for (i = 0; i < len; i++)
+ jp = new(g) JSON();
+ jp->s = s;
+ jp->len = len;
+ jp->pty = pty;
+
+ for (i = 0; i < jp->len; i++)
switch (s[i]) {
case '[':
if (jsp)
- goto tryit;
- else if (!(jsp = ParseArray(g, ++i, src, pty)))
- throw 1;
+ jsp = jp->ParseAsArray(g, i, pretty, ptyp);
+ else
+ jsp = jp->ParseArray(g, ++i);
break;
case '{':
if (jsp)
- goto tryit;
- else if (!(jsp = ParseObject(g, ++i, src, pty)))
+ jsp = jp->ParseAsArray(g, i, pretty, ptyp);
+ else if (!(jsp = jp->ParseObject(g, ++i)))
throw 2;
break;
@@ -157,8 +158,8 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
/* falls through */
default:
if (jsp)
- goto tryit;
- else if (!(jsp = ParseValue(g, i, src, pty)))
+ jsp = jp->ParseAsArray(g, i, pretty, ptyp);
+ else if (!(jsp = jp->ParseValue(g, i)))
throw 4;
break;
@@ -187,10 +188,17 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
} // end catch
return jsp;
+} // end of ParseJson
-tryit:
+/***********************************************************************/
+/* Parse several items as being in an array. */
+/***********************************************************************/
+PJAR JSON::ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp)
+{
if (pty[0] && (!pretty || pretty > 2)) {
- if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3)
+ PJAR jsp;
+
+ if ((jsp = ParseArray(g, (i = 0))) && ptyp && pretty == 3)
*ptyp = (pty[0]) ? 0 : 3;
return jsp;
@@ -198,26 +206,23 @@ tryit:
strcpy(g->Message, "More than one item in file");
return NULL;
-} // end of ParseJson
+} // end of ParseAsArray
/***********************************************************************/
/* Parse a JSON Array. */
/***********************************************************************/
-PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
+PJAR JSON::ParseArray(PGLOBAL g, int& i)
{
- char *s = src.str;
- int len = src.len;
- int level = 0;
- bool b = (!i);
- PJAR jarp = new(g) JARRAY;
- PJVAL jvp = NULL;
+ int level = 0;
+ bool b = (!i);
+ PJAR jarp = new(g) JARRAY;
for (; i < len; i++)
switch (s[i]) {
case ',':
if (level < 2) {
sprintf(g->Message, "Unexpected ',' near %.*s",ARGS);
- return NULL;
+ throw 1;
} else
level = 1;
@@ -225,8 +230,8 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
case ']':
if (level == 1) {
sprintf(g->Message, "Unexpected ',]' near %.*s", ARGS);
- return NULL;
- } // endif level
+ throw 1;
+ } // endif level
jarp->InitArray(g);
return jarp;
@@ -240,11 +245,9 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
default:
if (level == 2) {
sprintf(g->Message, "Unexpected value near %.*s", ARGS);
- return NULL;
- } else if ((jvp = ParseValue(g, i, src, pty)))
- jarp->AddValue(g, jvp);
- else
- return NULL;
+ throw 1;
+ } else
+ jarp->AddValue(g, ParseValue(g, i));
level = (b) ? 1 : 2;
break;
@@ -256,18 +259,15 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
return jarp;
} // endif b
- strcpy(g->Message, "Unexpected EOF in array");
- return NULL;
+ throw ("Unexpected EOF in array");
} // end of ParseArray
/***********************************************************************/
/* Parse a JSON Object. */
/***********************************************************************/
-PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
+PJOB JSON::ParseObject(PGLOBAL g, int& i)
{
PSZ key;
- char *s = src.str;
- int len = src.len;
int level = 0;
PJOB jobp = new(g) JOBJECT;
PJPR jpp = NULL;
@@ -276,42 +276,37 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
switch (s[i]) {
case '"':
if (level < 2) {
- if ((key = ParseString(g, ++i, src))) {
- jpp = jobp->AddPair(g, key);
- level = 1;
- } else
- return NULL;
-
+ key = ParseString(g, ++i);
+ jpp = jobp->AddPair(g, key);
+ level = 1;
} else {
sprintf(g->Message, "misplaced string near %.*s", ARGS);
- return NULL;
+ throw 2;
} // endif level
break;
case ':':
if (level == 1) {
- if (!(jpp->Val = ParseValue(g, ++i, src, pty)))
- return NULL;
-
+ jpp->Val = ParseValue(g, ++i);
level = 2;
} else {
sprintf(g->Message, "Unexpected ':' near %.*s", ARGS);
- return NULL;
+ throw 2;
} // endif level
break;
case ',':
if (level < 2) {
sprintf(g->Message, "Unexpected ',' near %.*s", ARGS);
- return NULL;
+ throw 2;
} else
- level = 1;
+ level = 0;
break;
case '}':
- if (level == 1) {
+ if (level < 2) {
sprintf(g->Message, "Unexpected '}' near %.*s", ARGS);
- return NULL;
+ throw 2;
} // endif level
return jobp;
@@ -324,20 +319,19 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
default:
sprintf(g->Message, "Unexpected character '%c' near %.*s",
s[i], ARGS);
- return NULL;
+ throw 2;
}; // endswitch s[i]
strcpy(g->Message, "Unexpected EOF in Object");
- return NULL;
+ throw 2;
} // end of ParseObject
/***********************************************************************/
/* Parse a JSON Value. */
/***********************************************************************/
-PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
+PJVAL JSON::ParseValue(PGLOBAL g, int& i)
{
- char *strval, *s = src.str;
- int n, len = src.len;
+ int n;
PJVAL jvp = new(g) JVALUE;
for (; i < len; i++)
@@ -355,21 +349,13 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
suite:
switch (s[i]) {
case '[':
- if (!(jvp->Jsp = ParseArray(g, ++i, src, pty)))
- return NULL;
-
+ jvp->Jsp = ParseArray(g, ++i);
break;
case '{':
- if (!(jvp->Jsp = ParseObject(g, ++i, src, pty)))
- return NULL;
-
+ jvp->Jsp = ParseObject(g, ++i);
break;
case '"':
- if ((strval = ParseString(g, ++i, src)))
- jvp->Value = AllocateValue(g, strval, TYPE_STRING);
- else
- return NULL;
-
+ jvp->Value = AllocateValue(g, ParseString(g, ++i), TYPE_STRING);
break;
case 't':
if (!strncmp(s + i, "true", 4)) {
@@ -398,11 +384,9 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
break;
case '-':
default:
- if (s[i] == '-' || isdigit(s[i])) {
- if (!(jvp->Value = ParseNumeric(g, i, src)))
- goto err;
-
- } else
+ if (s[i] == '-' || isdigit(s[i]))
+ jvp->Value = ParseNumeric(g, i);
+ else
goto err;
}; // endswitch s[i]
@@ -410,25 +394,21 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
return jvp;
err:
- sprintf(g->Message, "Unexpected character '%c' near %.*s",
- s[i], ARGS);
- return NULL;
+ sprintf(g->Message, "Unexpected character '%c' near %.*s", s[i], ARGS);
+ throw 3;
} // end of ParseValue
/***********************************************************************/
/* Unescape and parse a JSON string. */
/***********************************************************************/
-char *ParseString(PGLOBAL g, int& i, STRG& src)
+char *JSON::ParseString(PGLOBAL g, int& i)
{
- char *s = src.str;
uchar *p;
- int n = 0, len = src.len;
+ int n = 0;
// Be sure of memory availability
- if (len + 1 - i > (signed)((PPOOLHEADER)g->Sarea)->FreeBlk) {
- strcpy(g->Message, "ParseString: Out of memory");
- return NULL;
- } // endif len
+ if (((size_t)len + 1 - i) > ((PPOOLHEADER)g->Sarea)->FreeBlk)
+ throw("ParseString: Out of memory");
// The size to allocate is not known yet
p = (uchar*)PlugSubAlloc(g, NULL, 0);
@@ -502,17 +482,16 @@ char *ParseString(PGLOBAL g, int& i, STRG& src)
}; // endswitch s[i]
err:
- strcpy(g->Message, "Unexpected EOF in String");
- return NULL;
+ throw("Unexpected EOF in String");
} // end of ParseString
/***********************************************************************/
/* Parse a JSON numeric value. */
/***********************************************************************/
-PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
+PVAL JSON::ParseNumeric(PGLOBAL g, int& i)
{
- char *s = src.str, buf[50];
- int n = 0, len = src.len;
+ char buf[50];
+ int n = 0;
short nd = 0;
bool has_dot = false;
bool has_e = false;
@@ -575,14 +554,11 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
i--; // Unstack following character
return valp;
- } else {
- strcpy(g->Message, "No digit found");
- return NULL;
- } // endif found_digit
+ } else
+ throw("No digit found");
err:
- strcpy(g->Message, "Unexpected EOF in number");
- return NULL;
+ throw("Unexpected EOF in number");
} // end of ParseNumeric
/***********************************************************************/
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 1d058ad575f..bc94b372133 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -1,10 +1,11 @@
/**************** json H Declares Source Code File (.H) ****************/
/* Name: json.h Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
+#include <mysql_com.h>
#include "value.h"
#if defined(_DEBUG)
@@ -44,15 +45,31 @@ typedef struct {
int len;
} STRG, *PSG;
+// BSON size should be equal on Linux and Windows
+#define BMX 255
+typedef struct BSON* PBSON;
+
+/***********************************************************************/
+/* Structure used to return binary json to Json UDF functions. */
+/***********************************************************************/
+struct BSON {
+ char Msg[BMX + 1];
+ char *Filename;
+ PGLOBAL G;
+ int Pretty;
+ ulong Reslen;
+ my_bool Changed;
+ PJSON Top;
+ PJSON Jsp;
+ PBSON Bsp;
+}; // end of struct BSON
+
+PBSON JbinAlloc(PGLOBAL g, UDF_ARGS* args, ulong len, PJSON jsp);
+
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
-PJSON ParseJson(PGLOBAL g, char *s, int n, int *prty = NULL, bool *b = NULL);
-PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty);
-PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty);
-PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty);
-char *ParseString(PGLOBAL g, int& i, STRG& src);
-PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
+PJSON ParseJson(PGLOBAL g, char* s, int n, int* prty = NULL, bool* b = NULL);
PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
bool SerializeArray(JOUT *js, PJAR jarp, bool b);
bool SerializeObject(JOUT *js, PJOB jobp);
@@ -130,7 +147,7 @@ class JOUTPRT : public JOUTFILE {
class JPAIR : public BLOCK {
friend class JOBJECT;
friend class JSNX;
- friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
+ friend class JSON;
friend bool SerializeObject(JOUT *, PJOB);
public:
JPAIR(PCSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
@@ -149,8 +166,9 @@ class JPAIR : public BLOCK {
/* Class JSON. The base class for all other json classes. */
/***********************************************************************/
class JSON : public BLOCK {
+ friend PJSON ParseJson(PGLOBAL, char*, int, int*, bool*);
public:
- JSON(void) {Size = 0;}
+ JSON(void) : s(NULL), len(0), pty(NULL) {Size = 0;}
int size(void) {return Size;}
virtual int GetSize(bool b) {return Size;}
@@ -187,14 +205,27 @@ class JSON : public BLOCK {
virtual bool IsNull(void) {X return true;}
protected:
- int Size;
+ PJAR ParseArray(PGLOBAL g, int& i);
+ PJOB ParseObject(PGLOBAL g, int& i);
+ PJVAL ParseValue(PGLOBAL g, int& i);
+ char *ParseString(PGLOBAL g, int& i);
+ PVAL ParseNumeric(PGLOBAL g, int& i);
+ PJAR ParseAsArray(PGLOBAL g, int& i, int pretty, int *ptyp);
+
+ // Members
+ int Size;
+
+ // Only used when parsing
+ private:
+ char *s;
+ int len;
+ bool *pty;
}; // end of class JSON
/***********************************************************************/
/* Class JOBJECT: contains a list of value pairs. */
/***********************************************************************/
class JOBJECT : public JSON {
- friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB);
friend class JSNX;
public:
@@ -260,8 +291,8 @@ class JVALUE : public JSON {
friend class JARRAY;
friend class JSNX;
friend class JSONCOL;
- friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
- friend bool SerializeValue(JOUT *, PJVAL);
+ friend class JSON;
+ friend bool SerializeValue(JOUT*, PJVAL);
public:
JVALUE(void) : JSON() {Clear();}
JVALUE(PJSON jsp);
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index edd596ea02e..9ea37fb651d 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -25,7 +25,7 @@
#else
#define PUSH_WARNING(M) htrc(M)
#endif
-#define M 7
+#define M 9
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
@@ -1076,29 +1076,10 @@ my_bool JSNX::AddPath(void)
/* --------------------------------- JSON UDF ---------------------------------- */
-// BSON size should be equal on Linux and Windows
-#define BMX 255
-typedef struct BSON *PBSON;
-
-/*********************************************************************************/
-/* Structure used to return binary json. */
-/*********************************************************************************/
-struct BSON {
- char Msg[BMX + 1];
- char *Filename;
- PGLOBAL G;
- int Pretty;
- ulong Reslen;
- my_bool Changed;
- PJSON Top;
- PJSON Jsp;
- PBSON Bsp;
-}; // end of struct BSON
-
/*********************************************************************************/
/* Allocate and initialize a BSON structure. */
/*********************************************************************************/
-static PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
+PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
{
PBSON bsp = (PBSON)PlgDBSubAlloc(g, NULL, sizeof(BSON));
@@ -1111,7 +1092,7 @@ static PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
bsp->Reslen = len;
bsp->Changed = false;
bsp->Top = bsp->Jsp = jsp;
- bsp->Bsp = (IsJson(args, 0) == 3) ? (PBSON)args->args[0] : NULL;
+ bsp->Bsp = (args && IsJson(args, 0) == 3) ? (PBSON)args->args[0] : NULL;
} else
PUSH_WARNING(g->Message);
@@ -1144,7 +1125,7 @@ static my_bool JsonSubSet(PGLOBAL g)
{
PPOOLHEADER pph = (PPOOLHEADER)g->Sarea;
- pph->To_Free = (OFFSET)((g->Createas) ? g->Createas : sizeof(POOLHEADER));
+ pph->To_Free = (g->Saved_Size) ? g->Saved_Size : (size_t)sizeof(POOLHEADER);
pph->FreeBlk = g->Sarea_Size - pph->To_Free;
return FALSE;
} /* end of JsonSubSet */
@@ -1154,7 +1135,7 @@ static my_bool JsonSubSet(PGLOBAL g)
/*********************************************************************************/
inline void JsonMemSave(PGLOBAL g)
{
- g->Createas = (int)((PPOOLHEADER)g->Sarea)->To_Free;
+ g->Saved_Size = ((PPOOLHEADER)g->Sarea)->To_Free;
} /* end of JsonMemSave */
/*********************************************************************************/
@@ -1422,7 +1403,7 @@ static int IsJson(UDF_ARGS *args, uint i, bool b)
n = 2; // arg is a json file name
} else if (b) {
char *sap;
- PGLOBAL g = PlugInit(NULL, args->lengths[i] * M + 1024);
+ PGLOBAL g = PlugInit(NULL, (size_t)args->lengths[i] * M + 1024);
JsonSubSet(g);
sap = MakePSZ(g, args, i);
@@ -1625,7 +1606,7 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
return true;
} // endif SareaAlloc
- g->Createas = 0;
+ g->Saved_Size = 0;
g->Xchk = NULL;
initid->max_length = rl;
} // endif Size
@@ -4425,13 +4406,15 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
fn = MakePSZ(g, args, 0);
if (args->arg_count > 1) {
- int len, pretty, pty = 3;
+ int len, pretty = 3, pty = 3;
PJSON jsp;
PJVAL jvp = NULL;
- pretty = (args->arg_type[1] == INT_RESULT) ? (int)*(longlong*)args->args[1]
- : (args->arg_count > 2 && args->arg_type[2] == INT_RESULT)
- ? (int)*(longlong*)args->args[2] : 3;
+ for (unsigned int i = 1; i < args->arg_count; i++)
+ if (args->arg_type[i] == INT_RESULT && *(longlong*)args->args[i] < 4) {
+ pretty = (int) * (longlong*)args->args[i];
+ break;
+ } // endif type
/*******************************************************************************/
/* Parse the json file and allocate its tree structure. */
@@ -4499,6 +4482,7 @@ my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // endif
CalcLen(args, false, reslen, memlen);
+ memlen = memlen + 5000; // To take care of not pretty files
return JsonInit(initid, args, message, true, reslen, memlen);
} // end of jfile_make_init
@@ -5628,20 +5612,19 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else if (args->arg_type[0] != STRING_RESULT || !args->args[0]) {
strcpy(message, "First argument must be a constant string (file name)");
return true;
- } else if (args->arg_count > 1 && args->arg_type[1] != STRING_RESULT) {
- strcpy(message, "Second argument is not a string (path)");
- return true;
- } else if (args->arg_count > 2 && args->arg_type[2] != INT_RESULT) {
- strcpy(message, "Third argument is not an integer (pretty)");
- return true;
- } else if (args->arg_count > 3) {
- if (args->arg_type[3] != INT_RESULT) {
- strcpy(message, "Fourth argument is not an integer (memory)");
+ } // endifs
+
+ for (unsigned int i = 1; i < args->arg_count; i++) {
+ if (!(args->arg_type[i] == INT_RESULT || args->arg_type[i] == STRING_RESULT)) {
+ sprintf(message, "Argument %d is not an integer or a string (pretty or path)", i);
return true;
- } else
- more += (ulong)*(longlong*)args->args[3];
+ } // endif arg_type
- } // endifs
+ // Take care of eventual memory argument
+ if (args->arg_type[i] == INT_RESULT && args->args[i])
+ more += (ulong) * (longlong*)args->args[i];
+
+ } // endfor i
initid->maybe_null = 1;
CalcLen(args, false, reslen, memlen);
@@ -5656,7 +5639,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
char *fn;
- int pretty, len = 0, pty = 3;
+ int pretty = 3, len = 0, pty = 3;
PJSON jsp;
PJVAL jvp = NULL;
PGLOBAL g = (PGLOBAL)initid->ptr;
@@ -5668,7 +5651,12 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
fn = MakePSZ(g, args, 0);
- pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3;
+
+ for (unsigned int i = 1; i < args->arg_count; i++)
+ if (args->arg_type[i] == INT_RESULT && *(longlong*)args->args[i] < 4) {
+ pretty = (int) * (longlong*)args->args[i];
+ break;
+ } // endif type
/*********************************************************************************/
/* Parse the json file and allocate its tree structure. */
@@ -5759,7 +5747,7 @@ char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result,
// Keep result of constant function
g->Xchk = (initid->const_item) ? str : NULL;
} else {
- *error = 1;
+ // *error = 1;
str = strcpy(result, "Argument is not a Jbin tree");
} // endif
@@ -5776,6 +5764,474 @@ void json_serialize_deinit(UDF_INIT* initid)
} // end of json_serialize_deinit
/*********************************************************************************/
+/* Convert a prettiest Json file to Pretty=0. */
+/*********************************************************************************/
+my_bool jfile_convert_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 3) {
+ strcpy(message, "This function must have 3 arguments");
+ return true;
+ } else if (args->arg_type[2] != INT_RESULT) {
+ strcpy(message, "Third Argument must be an integer (LRECL)");
+ return true;
+ } else for (int i = 0; i < 2; i++)
+ if (args->arg_type[i] != STRING_RESULT) {
+ sprintf(message, "Arguments %d must be a string (file name)", i+1);
+ return true;
+ } // endif args
+
+ CalcLen(args, false, reslen, memlen);
+ return JsonInit(initid, args, message, false, reslen, memlen);
+} // end of jfile_convert_init
+
+char *jfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result,
+ unsigned long *res_length, char *, char *error) {
+ char *str, *fn, *ofn;
+ int lrecl = (int)*(longlong*)args->args[2];
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ PlugSubSet(g->Sarea, g->Sarea_Size);
+ fn = MakePSZ(g, args, 0);
+ ofn = MakePSZ(g, args, 1);
+
+ if (!g->Xchk) {
+ JUP* jup = new(g) JUP(g);
+
+ str = jup->UnprettyJsonFile(g, fn, ofn, lrecl);
+ g->Xchk = str;
+ } else
+ str = (char*)g->Xchk;
+
+ if (!str) {
+ str = PlugDup(g, g->Message);
+ } // endif str
+
+ *res_length = strlen(str);
+ return str;
+} // end of jfile_convert
+
+void jfile_convert_deinit(UDF_INIT* initid) {
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of jfile_convert_deinit
+
+/* --------------------------------- Class JUP --------------------------------- */
+
+#define ARGS MY_MIN(24,len-i),s+MY_MAX(i-3,0)
+
+/*********************************************************************************/
+/* JUP public constructor. */
+/*********************************************************************************/
+JUP::JUP(PGLOBAL g) {
+ fs = NULL;
+ s = buff = NULL;
+ i = k = len = recl = 0;
+} // end of JUP constructor
+
+/*********************************************************************************/
+/* Copy a json file to another with pretty = 0. */
+/*********************************************************************************/
+char* JUP::UnprettyJsonFile(PGLOBAL g, char *fn, char *outfn, int lrecl) {
+ char *ret = NULL;
+ HANDLE hFile;
+ MEMMAP mm;
+
+ /*******************************************************************************/
+ /* Create the mapping file object. */
+ /*******************************************************************************/
+ hFile = CreateFileMap(g, fn, &mm, MODE_READ, false);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ DWORD rc = GetLastError();
+
+ if (!(*g->Message))
+ sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int)rc, fn);
+
+ return NULL;
+ } // endif hFile
+
+ /*******************************************************************************/
+ /* Get the file size (assuming file is smaller than 4 GB) */
+ /*******************************************************************************/
+ if (!mm.lenL) { // Empty or deleted file
+ CloseFileHandle(hFile);
+ return NULL;
+ } else
+ len = (int)mm.lenL;
+
+ if (!mm.memory) {
+ CloseFileHandle(hFile);
+ sprintf(g->Message, MSG(MAP_VIEW_ERROR), fn, GetLastError());
+ return NULL;
+ } else
+ s = (char*)mm.memory;
+
+ CloseFileHandle(hFile); // Not used anymore
+
+ /*********************************************************************************/
+ /* Parse the json file and allocate its tree structure. */
+ /*********************************************************************************/
+ if (!(fs = fopen(outfn, "wb"))) {
+ sprintf(g->Message, MSG(OPEN_MODE_ERROR),
+ "w", (int)errno, outfn);
+ strcat(strcat(g->Message, ": "), strerror(errno));
+ CloseMemMap(mm.memory, (size_t)mm.lenL);
+ return NULL;
+ } // endif fs
+
+ g->Message[0] = 0;
+
+ if (!unPretty(g, lrecl))
+ ret = outfn;
+
+ CloseMemMap(mm.memory, (size_t)mm.lenL);
+ fclose(fs);
+ return ret;
+} // end of UnprettyJsonFile
+
+/***********************************************************************/
+/* Translate a json file to pretty = 0. */
+/***********************************************************************/
+bool JUP::unPretty(PGLOBAL g, int lrecl) {
+ bool go, next, rc = false;
+
+ if (trace(1))
+ htrc("UnPretty: s=%.10s len=%zd lrecl=%d\n", s, len, lrecl);
+
+ if (!s || !len) {
+ strcpy(g->Message, "Void JSON file");
+ return true;
+ } else if (*s != '[') {
+ // strcpy(g->Message, "JSON file is not an array");
+ s = strchr(s, '[');
+ // return true;
+ } // endif s
+
+ i = 1;
+ go = next = true;
+
+ try {
+ // Allocate the record
+ buff = (char*)PlugSubAlloc(g, NULL, (size_t)lrecl + 3);
+ recl = lrecl;
+
+ do {
+ for (k = 0; go && i < len; i++)
+ switch (s[i]) {
+ case '{':
+ buff[k++] = s[i++];
+ CopyObject(g);
+ break;
+ case '[':
+ throw "JSON file is not an array of objects";
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ case ',':
+ go = false;
+ break;
+ case ']':
+ go = next = false;
+ break;
+ default:
+ sprintf(g->Message, "Unexpected '%c' near %.*s", s[i], ARGS);
+ throw 4;
+ break;
+ }; // endswitch s[i]
+
+ // Write the record
+#ifdef __win_
+ buff[k++] = '\r';
+#endif
+ buff[k++] = '\n';
+ buff[k] = 0;
+
+ if ((fputs(buff, fs)) == EOF) {
+ sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno));
+ throw 5;
+ } // endif EOF
+
+ go = true;
+ } while (next);
+
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+ rc = true;
+ } catch (const char* msg) {
+ strcpy(g->Message, msg);
+ rc = true;
+ } // end catch
+
+ return rc;
+} // end of unPretty
+
+/***********************************************************************/
+/* Copy a JSON Object. */
+/***********************************************************************/
+void JUP::CopyObject(PGLOBAL g) {
+ int level = 0;
+
+ for (; i < len; i++)
+ switch (s[i]) {
+ case '"':
+ AddBuff(s[i++]);
+
+ if (level < 2) {
+ CopyString(g);
+ level = 1;
+ } else {
+ sprintf(g->Message, "misplaced string near %.*s", ARGS);
+ throw 3;
+ } // endif level
+
+ break;
+ case ':':
+ AddBuff(s[i++]);
+
+ if (level == 1) {
+ CopyValue(g);
+ level = 2;
+ } else {
+ sprintf(g->Message, "Unexpected ':' near %.*s", ARGS);
+ throw 3;
+ } // endif level
+
+ break;
+ case ',':
+ AddBuff(s[i]);
+
+ if (level < 2) {
+ sprintf(g->Message, "Unexpected ',' near %.*s", ARGS);
+ throw 3;
+ } else
+ level = 0;
+
+ break;
+ case '}':
+ AddBuff(s[i]);
+
+ if (level == 1) {
+ sprintf(g->Message, "Unexpected '}' near %.*s", ARGS);
+ throw 3;
+ } // endif level
+
+ return;
+ case '\n':
+ case '\r':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ sprintf(g->Message, "Unexpected character '%c' near %.*s", s[i], ARGS);
+ throw 3;
+ }; // endswitch s[i]
+
+ throw "Unexpected EOF in Object";
+} // end of CopyObject
+
+/***********************************************************************/
+/* Copy a JSON Array. */
+/***********************************************************************/
+void JUP::CopyArray(PGLOBAL g) {
+ int level = 0;
+
+ for (; i < len; i++)
+ switch (s[i]) {
+ case ',':
+ if (level < 2) {
+ sprintf(g->Message, "Unexpected ',' near %.*s", ARGS);
+ throw 2;
+ } else
+ level = 1;
+
+ AddBuff(s[i]);
+ break;
+ case ']':
+ if (level == 1) {
+ sprintf(g->Message, "Unexpected ',]' near %.*s", ARGS);
+ throw 2;
+ } // endif level
+
+ AddBuff(s[i]);
+ return;
+ case '\n':
+ case '\r':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ if (level == 2) {
+ sprintf(g->Message, "Unexpected value near %.*s", ARGS);
+ throw 2;
+ } // endif level
+
+ CopyValue(g);
+ level = 2;
+ break;
+ }; // endswitch s[i]
+
+ throw "Unexpected EOF in array";
+} // end of CopyArray
+
+/***********************************************************************/
+/* Copy a JSON Value. */
+/***********************************************************************/
+void JUP::CopyValue(PGLOBAL g) {
+ for (; i < len; i++)
+ switch (s[i]) {
+ case '\n':
+ case '\r':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ goto suite;
+ } // endswitch
+
+suite:
+ switch (s[i]) {
+ case '[':
+ AddBuff(s[i++]);
+ CopyArray(g);
+ break;
+ case '{':
+ AddBuff(s[i++]);
+ CopyObject(g);
+ break;
+ case '"':
+ AddBuff(s[i++]);
+ CopyString(g);
+ break;
+ case 't':
+ if (!strncmp(s + i, "true", 4)) {
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i]);
+ } else
+ goto err;
+
+ break;
+ case 'f':
+ if (!strncmp(s + i, "false", 5)) {
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i]);
+ } else
+ goto err;
+
+ break;
+ case 'n':
+ if (!strncmp(s + i, "null", 4)) {
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i++]);
+ AddBuff(s[i]);
+ } else
+ goto err;
+
+ break;
+ default:
+ if (s[i] == '-' || isdigit(s[i]))
+ CopyNumeric(g);
+ else
+ goto err;
+
+ }; // endswitch s[i]
+
+ return;
+
+err:
+ sprintf(g->Message, "Unexpected character '%c' near %.*s", s[i], ARGS);
+ throw 1;
+} // end of CopyValue
+
+/***********************************************************************/
+/* Unescape and parse a JSON string. */
+/***********************************************************************/
+void JUP::CopyString(PGLOBAL g) {
+ for (; i < len; i++) {
+ AddBuff(s[i]);
+
+ switch (s[i]) {
+ case '"':
+ return;
+ case '\\':
+ AddBuff(s[++i]);
+ break;
+ default:
+ break;
+ }; // endswitch s[i]
+
+ } // endfor i
+
+ throw "Unexpected EOF in String";
+} // end of CopyString
+
+/***********************************************************************/
+/* Copy a JSON numeric value. */
+/***********************************************************************/
+void JUP::CopyNumeric(PGLOBAL g) {
+ bool has_dot = false;
+ bool has_e = false;
+ bool found_digit = false;
+
+ for (; i < len; i++) {
+ switch (s[i]) {
+ case '.':
+ if (!found_digit || has_dot || has_e)
+ goto err;
+
+ has_dot = true;
+ break;
+ case 'e':
+ case 'E':
+ if (!found_digit || has_e)
+ goto err;
+
+ has_e = true;
+ found_digit = false;
+ break;
+ case '+':
+ if (!has_e)
+ goto err;
+
+ // fall through
+ case '-':
+ if (found_digit)
+ goto err;
+
+ break;
+ default:
+ if (isdigit(s[i])) {
+ found_digit = true;
+ } else
+ goto fin;
+
+ }; // endswitch s[i]
+
+ AddBuff(s[i]);
+ } // endfor i
+
+fin:
+ if (!found_digit)
+ throw "No digit found";
+ else
+ i--;
+
+ return;
+
+err:
+ throw "Unexpected EOF in number";
+} // end of CopyNumeric
+
+/*********************************************************************************/
/* Utility function returning an environment variable value. */
/*********************************************************************************/
my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index ee56869a111..897b0fe9919 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -235,6 +235,10 @@ extern "C" {
DllExport char *json_serialize(UDF_EXEC_ARGS);
DllExport void json_serialize_deinit(UDF_INIT*);
+ DllExport my_bool jfile_convert_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport char* jfile_convert(UDF_EXEC_ARGS);
+ DllExport void jfile_convert_deinit(UDF_INIT*);
+
DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *envar(UDF_EXEC_ARGS);
@@ -324,3 +328,38 @@ protected:
my_bool Wr; // Write mode
my_bool Jb; // Must return json item
}; // end of class JSNX
+
+/*********************************************************************************/
+/* Class JUP: used by jfile_convert to make a json file pretty = 0. */
+/*********************************************************************************/
+class JUP : public BLOCK {
+public:
+ // Constructor
+ JUP(PGLOBAL g);
+
+ // Implementation
+ void AddBuff(char c) {
+ if (k < recl)
+ buff[k++] = c;
+ else
+ throw "Record size is too small";
+ } // end of AddBuff
+
+ // Methods
+ char *UnprettyJsonFile(PGLOBAL g, char* fn, char* outfn, int lrecl);
+ bool unPretty(PGLOBAL g, int lrecl);
+ void CopyObject(PGLOBAL g);
+ void CopyArray(PGLOBAL g);
+ void CopyValue(PGLOBAL g);
+ void CopyString(PGLOBAL g);
+ void CopyNumeric(PGLOBAL g);
+
+ // Members
+ FILE* fs;
+ char* s;
+ char* buff;
+ int len;
+ int recl;
+ int i, k;
+}; // end of class JUP
+
diff --git a/storage/connect/mongo.cpp b/storage/connect/mongo.cpp
index bd3d3b893c1..5f10a89ee67 100644
--- a/storage/connect/mongo.cpp
+++ b/storage/connect/mongo.cpp
@@ -35,6 +35,7 @@
bool MakeSelector(PGLOBAL g, PFIL fp, PSTRG s);
bool IsNum(PSZ s);
+int GetDefaultDepth(void);
/***********************************************************************/
/* Make selector json representation for Mongo tables. */
@@ -248,15 +249,10 @@ MGODISC::MGODISC(PGLOBAL g, int *lg) {
/***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
{
- PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
PMGODEF tdp;
- if (level) {
- lvl = atoi(level);
- lvl = (lvl > 16) ? 16 : lvl;
- } else
- lvl = 0;
-
+ lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
+ lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
all = GetBooleanTableOption(g, topt, "Fullarray", false);
/*********************************************************************/
diff --git a/storage/connect/mysql-test/connect/r/json_java_2.result b/storage/connect/mysql-test/connect/r/json_java_2.result
index 4bbac236200..47fc4abbd28 100644
--- a/storage/connect/mysql-test/connect/r/json_java_2.result
+++ b/storage/connect/mysql-test/connect/r/json_java_2.result
@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
-address_coord 1 CHAR 256 256 0 1 address.coord
+address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades_date 1 CHAR 256 256 0 1 grades.0.date
+grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=2' CONNECTION='mongodb://localhost:2701
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' `LRECL`=4096
@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=2';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` double(18,16) DEFAULT NULL `JPATH`='address.coord.0',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_date` char(24) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` char(24) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' `LRECL`=4096
diff --git a/storage/connect/mysql-test/connect/r/json_java_3.result b/storage/connect/mysql-test/connect/r/json_java_3.result
index eb8bfc022d6..720c82cd7f9 100644
--- a/storage/connect/mysql-test/connect/r/json_java_3.result
+++ b/storage/connect/mysql-test/connect/r/json_java_3.result
@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
-address_coord 1 CHAR 256 256 0 1 address.coord
+address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades_date 1 CHAR 256 256 0 1 grades.0.date
+grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=Java,Version=3' CONNECTION='mongodb://localhost:2701
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' `LRECL`=4096
@@ -251,15 +251,15 @@ OPTION_LIST='Driver=Java,level=2,version=3';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` double(18,16) DEFAULT NULL `JPATH`='address.coord.0',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` bigint(13) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' `LRECL`=4096
diff --git a/storage/connect/mysql-test/connect/r/json_mongo_c.result b/storage/connect/mysql-test/connect/r/json_mongo_c.result
index 550e94f286e..f9bfc01763e 100644
--- a/storage/connect/mysql-test/connect/r/json_mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/json_mongo_c.result
@@ -20,12 +20,12 @@ SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
-address_coord 1 CHAR 256 256 0 1 address.coord
+address_coord 1 CHAR 1024 1024 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades_date 1 CHAR 256 256 0 1 grades.0.date
+grades_date 1 CHAR 1024 1024 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
@@ -64,16 +64,16 @@ OPTION_LIST='Level=1,Driver=C,Version=0' CONNECTION='mongodb://localhost:27017'
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` varchar(1024) DEFAULT NULL `JPATH`='address.coord',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` varchar(1024) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' `LRECL`=1024
@@ -251,15 +251,15 @@ OPTION_LIST='Driver=C,level=2,version=0';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
- `address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
- `address_coord` double(23,20) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
- `address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
- `address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
+ `_id` char(24) NOT NULL `JPATH`='_id',
+ `address_building` char(10) NOT NULL `JPATH`='address.building',
+ `address_coord` double(23,20) DEFAULT NULL `JPATH`='address.coord.0',
+ `address_street` char(38) NOT NULL `JPATH`='address.street',
+ `address_zipcode` char(5) NOT NULL `JPATH`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
- `grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
- `grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
+ `grades_date` bigint(13) DEFAULT NULL `JPATH`='grades.0.date',
+ `grades_grade` char(14) DEFAULT NULL `JPATH`='grades.0.grade',
+ `grades_score` bigint(2) DEFAULT NULL `JPATH`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' `LRECL`=1024
diff --git a/storage/connect/mysql-test/connect/r/updelx.result b/storage/connect/mysql-test/connect/r/updelx.result
index 2aed1e06928..bb82afcc1a8 100644
--- a/storage/connect/mysql-test/connect/r/updelx.result
+++ b/storage/connect/mysql-test/connect/r/updelx.result
@@ -978,7 +978,7 @@ DROP TABLE t1;
# FIX table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
-msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
+msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4;
Warnings:
Warning 1105 No file name. Table will use t1.fix
@@ -1345,7 +1345,7 @@ DROP TABLE t1;
# BIN table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
-msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
+msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8;
Warnings:
Warning 1105 No file name. Table will use t1.bin
diff --git a/storage/connect/mysql-test/connect/t/updelx.test b/storage/connect/mysql-test/connect/t/updelx.test
index 19d0d790a30..f6291432e48 100644
--- a/storage/connect/mysql-test/connect/t/updelx.test
+++ b/storage/connect/mysql-test/connect/t/updelx.test
@@ -36,7 +36,7 @@ DROP TABLE t1;
--echo # FIX table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
-msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
+msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
@@ -48,7 +48,7 @@ DROP TABLE t1;
--echo # BIN table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
-msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
+msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
diff --git a/storage/connect/myutil.h b/storage/connect/myutil.h
index 6991172b39e..fa41fa47d61 100644
--- a/storage/connect/myutil.h
+++ b/storage/connect/myutil.h
@@ -6,8 +6,8 @@
enum enum_field_types PLGtoMYSQL(int type, bool dbf, char var = 0);
const char *PLGtoMYSQLtype(int type, bool dbf, char var = 0);
-int MYSQLtoPLG(char *typname, char *var = NULL);
-int MYSQLtoPLG(int mytype, char *var = NULL);
+int MYSQLtoPLG(char *typname, char *var);
+int MYSQLtoPLG(int mytype, char *var);
PCSZ MyDateFmt(int mytype);
PCSZ MyDateFmt(char *typname);
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index c20c3d56c3f..bdfa3462c28 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2018 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2020 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -1245,7 +1245,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
mp.Sub = mp.Size <= ((mp.Sub) ? maxsub : (maxsub >> 2));
if (trace(2))
- htrc("PlgDBalloc: in %p size=%d used=%d free=%d sub=%d\n",
+ htrc("PlgDBalloc: in %p size=%zd used=%zd free=%zd sub=%d\n",
arp, mp.Size, pph->To_Free, pph->FreeBlk, mp.Sub);
if (!mp.Sub) {
@@ -1261,7 +1261,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
mp.Memp = malloc(mp.Size);
if (trace(8))
- htrc("PlgDBalloc: %s(%d) at %p\n", v, mp.Size, mp.Memp);
+ htrc("PlgDBalloc: %s(%zd) at %p\n", v, mp.Size, mp.Memp);
if (!mp.Inlist && mp.Memp) {
// New allocated block, put it in the memory block chain.
@@ -1293,7 +1293,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
#endif
if (trace(2))
- htrc("PlgDBrealloc: %p size=%d sub=%d\n", mp.Memp, mp.Size, mp.Sub);
+ htrc("PlgDBrealloc: %p size=%zd sub=%d\n", mp.Memp, mp.Size, mp.Sub);
if (newsize == mp.Size)
return mp.Memp; // Nothing to do
@@ -1343,7 +1343,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
} // endif's
if (trace(8))
- htrc(" newsize=%d newp=%p sub=%d\n", mp.Size, mp.Memp, mp.Sub);
+ htrc(" newsize=%zd newp=%p sub=%d\n", mp.Size, mp.Memp, mp.Sub);
return mp.Memp;
} // end of PlgDBrealloc
@@ -1395,13 +1395,13 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
pph = (PPOOLHEADER)memp;
if (trace(16))
- htrc("PlgDBSubAlloc: memp=%p size=%d used=%d free=%d\n",
+ htrc("PlgDBSubAlloc: memp=%p size=%zd used=%zd free=%zd\n",
memp, size, pph->To_Free, pph->FreeBlk);
- if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
+ if (size > pph->FreeBlk) { /* Not enough memory left in pool */
sprintf(g->Message,
- "Not enough memory in Work area for request of %d (used=%d free=%d)",
- (int) size, pph->To_Free, pph->FreeBlk);
+ "Not enough memory in Work area for request of %zd (used=%zd free=%zd)",
+ size, pph->To_Free, pph->FreeBlk);
if (trace(1))
htrc("%s\n", g->Message);
@@ -1417,7 +1417,7 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
pph->FreeBlk -= size; // New size of pool free block
if (trace(16))
- htrc("Done memp=%p used=%d free=%d\n",
+ htrc("Done memp=%p used=%zd free=%zd\n",
memp, pph->To_Free, pph->FreeBlk);
return (memp);
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 3899379ade2..e45feb31bea 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -6,7 +6,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1993-2019 */
+/* (C) Copyright to the author Olivier BERTRAND 1993-2020 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -142,7 +142,7 @@ void htrc(char const* fmt, ...)
/* Language points on initial language name and eventual path. */
/* Return value is the pointer to the Global structure. */
/***********************************************************************/
-PGLOBAL PlugInit(LPCSTR Language, uint worksize)
+PGLOBAL PlugInit(LPCSTR Language, size_t worksize)
{
PGLOBAL g;
@@ -158,13 +158,14 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
} // end try/catch
g->Sarea = NULL;
- g->Createas = 0;
+ g->Createas = false;
g->Alchecked = 0;
g->Mrr = 0;
g->Activityp = NULL;
g->Xchk = NULL;
g->N = 0;
g->More = 0;
+ g->Saved_Size = 0;
strcpy(g->Message, "");
/*******************************************************************/
@@ -459,7 +460,7 @@ short GetLineLength(PGLOBAL g)
/***********************************************************************/
/* Program for memory allocation of work and language areas. */
/***********************************************************************/
-bool AllocSarea(PGLOBAL g, uint size)
+bool AllocSarea(PGLOBAL g, size_t size)
{
/*********************************************************************/
/* This is the allocation routine for the WIN32/UNIX/AIX version. */
@@ -483,7 +484,7 @@ bool AllocSarea(PGLOBAL g, uint size)
if (trace(8)) {
#endif
if (g->Sarea)
- htrc("Work area of %u allocated at %p\n", size, g->Sarea);
+ htrc("Work area of %zd allocated at %p\n", size, g->Sarea);
else
htrc("SareaAlloc: %-.256s\n", g->Message);
@@ -510,7 +511,7 @@ void FreeSarea(PGLOBAL g)
#else
if (trace(8))
#endif
- htrc("Freeing Sarea at %p size = %d\n", g->Sarea, g->Sarea_Size);
+ htrc("Freeing Sarea at %p size = %zd\n", g->Sarea, g->Sarea_Size);
g->Sarea = NULL;
g->Sarea_Size = 0;
@@ -524,11 +525,11 @@ void FreeSarea(PGLOBAL g)
/* Here there should be some verification done such as validity of */
/* the address and size not larger than memory size. */
/***********************************************************************/
-BOOL PlugSubSet(void *memp, uint size)
+BOOL PlugSubSet(void *memp, size_t size)
{
PPOOLHEADER pph = (PPOOLHEADER)memp;
- pph->To_Free = (OFFSET)sizeof(POOLHEADER);
+ pph->To_Free = (size_t)sizeof(POOLHEADER);
pph->FreeBlk = size - pph->To_Free;
return FALSE;
} /* end of PlugSubSet */
@@ -560,15 +561,15 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
pph = (PPOOLHEADER)memp;
if (trace(16))
- htrc("SubAlloc in %p size=%d used=%d free=%d\n",
+ htrc("SubAlloc in %p size=%zd used=%zd free=%zd\n",
memp, size, pph->To_Free, pph->FreeBlk);
- if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
+ if (size > pph->FreeBlk) { /* Not enough memory left in pool */
PCSZ pname = "Work";
sprintf(g->Message,
- "Not enough memory in %-.256s area for request of %u (used=%d free=%d)",
- pname, (uint)size, pph->To_Free, pph->FreeBlk);
+ "Not enough memory in %-.256s area for request of %zu (used=%zu free=%zu)",
+ pname, size, pph->To_Free, pph->FreeBlk);
if (trace(1))
htrc("PlugSubAlloc: %-.256s\n", g->Message);
@@ -580,11 +581,11 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
/* Do the suballocation the simplest way. */
/*********************************************************************/
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
- pph->To_Free += (OFFSET)size; /* New offset of pool free block */
- pph->FreeBlk -= (uint)size; /* New size of pool free block */
+ pph->To_Free += size; /* New offset of pool free block */
+ pph->FreeBlk -= size; /* New size of pool free block */
if (trace(16))
- htrc("Done memp=%p used=%d free=%d\n",
+ htrc("Done memp=%p used=%zd free=%zd\n",
memp, pph->To_Free, pph->FreeBlk);
return (memp);
@@ -605,40 +606,4 @@ char *PlugDup(PGLOBAL g, const char *str)
} // end of PlugDup
-#if 0
-/***********************************************************************/
-/* This routine suballocate a copy of the passed string. */
-/***********************************************************************/
-char *PlugDup(PGLOBAL g, const char *str)
- {
- char *buf;
- size_t len;
-
- if (str && (len = strlen(str))) {
- buf = (char*)PlugSubAlloc(g, NULL, len + 1);
- strcpy(buf, str);
- } else
- buf = NULL;
-
- return(buf);
- } /* end of PlugDup */
-#endif // 0
-
-/***********************************************************************/
-/* This routine makes a pointer from an offset to a memory pointer. */
-/***********************************************************************/
-void *MakePtr(void *memp, OFFSET offset)
- {
- return ((offset == 0) ? NULL : &((char *)memp)[offset]);
- } /* end of MakePtr */
-
-/***********************************************************************/
-/* This routine makes an offset from a pointer new format. */
-/***********************************************************************/
-#if 0
-OFFSET MakeOff(void *memp, void *ptr)
- {
- return ((!ptr) ? 0 : (OFFSET)((char *)ptr - (char *)memp));
- } /* end of MakeOff */
-#endif
/*--------------------- End of PLUGUTIL program -----------------------*/
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 692ca9d0258..dbcd590c3de 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -52,19 +52,10 @@
/* External functions. */
/***********************************************************************/
USETEMP UseTemp(void);
+bool JsonAllPath(void);
+int GetDefaultDepth(void);
char *GetJsonNull(void);
-//typedef struct _jncol {
-// struct _jncol *Next;
-// char *Name;
-// char *Fmt;
-// int Type;
-// int Len;
-// int Scale;
-// bool Cbn;
-// bool Found;
-//} JCOL, *PJCL;
-
/***********************************************************************/
/* JSONColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside a JSON file. */
@@ -167,23 +158,20 @@ JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
jsp = NULL;
row = NULL;
sep = NULL;
- i = n = bf = ncol = lvl = 0;
- all = false;
+ i = n = bf = ncol = lvl = sz = 0;
+ all = strfy = false;
} // end of JSONDISC constructor
int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
{
char filename[_MAX_PATH];
bool mgo = (GetTypeID(topt->type) == TAB_MONGO);
- PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
-
- if (level) {
- lvl = atoi(level);
- lvl = (lvl > 16) ? 16 : lvl;
- } else
- lvl = 0;
- sep = GetStringTableOption(g, topt, "Separator", ".");
+ lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
+ lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
+ sep = GetStringTableOption(g, topt, "Separator", ".");
+ sz = GetIntegerTableOption(g, topt, "Jsize", 1024);
+ strfy = GetBooleanTableOption(g, topt, "Stringify", false);
/*********************************************************************/
/* Open the input file. */
@@ -306,7 +294,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
// Allocate the parse work memory
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
memset(G, 0, sizeof(GLOBAL));
- G->Sarea_Size = tdp->Lrecl * 10;
+ G->Sarea_Size = (size_t)tdp->Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0;
@@ -403,7 +391,10 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
PJAR jar;
if ((valp = jvp ? jvp->GetValue() : NULL)) {
- jcol.Type = valp->GetType();
+ if (JsonAllPath() && !fmt[bf])
+ strcat(fmt, colname);
+
+ jcol.Type = valp->GetType();
jcol.Len = valp->GetValLen();
jcol.Scale = valp->GetValPrec();
jcol.Cbn = valp->IsNull();
@@ -482,8 +473,16 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
} // endswitch Type
} else if (lvl >= 0) {
- jcol.Type = TYPE_STRING;
- jcol.Len = 256;
+ if (strfy) {
+ if (!fmt[bf])
+ strcat(fmt, colname);
+
+ strcat(fmt, ".*");
+ } else if (JsonAllPath() && !fmt[bf])
+ strcat(fmt, colname);
+
+ jcol.Type = TYPE_STRING;
+ jcol.Len = sz;
jcol.Scale = 0;
jcol.Cbn = true;
} else
@@ -1489,7 +1488,18 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
Value->Reset();
- } else
+ } else if (Value->GetType() == TYPE_BIN) {
+ if ((unsigned)Value->GetClen() >= sizeof(BSON)) {
+ ulong len = Tjp->Lrecl ? Tjp->Lrecl : 500;
+ PBSON bsp = JbinAlloc(g, NULL, len, jsp);
+
+ strcat(bsp->Msg, " column");
+ ((BINVAL*)Value)->SetBinValue(bsp, sizeof(BSON));
+ } else {
+ strcpy(g->Message, "Column size too small");
+ Value->SetValue_char(NULL, 0);
+ } // endif Clen
+ } else
Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
return Value;
@@ -1985,8 +1995,9 @@ int TDBJSON::MakeNewDoc(PGLOBAL g)
/***********************************************************************/
int TDBJSON::MakeDocument(PGLOBAL g)
{
- char *p, *memory, *objpath, *key = NULL;
+ char *p, *p1, *p2, *memory, *objpath, *key = NULL;
int len, i = 0;
+ my_bool a;
MODE mode = Mode;
PJSON jsp;
PJOB objp = NULL;
@@ -2029,22 +2040,39 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if ((objpath = PlugDup(g, Objname))) {
if (*objpath == '$') objpath++;
if (*objpath == '.') objpath++;
+ p1 = (*objpath == '[') ? objpath++ : NULL;
/*********************************************************************/
/* Find the table in the tree structure. */
/*********************************************************************/
- for (; jsp && objpath; objpath = p) {
- if ((p = strchr(objpath, Sep)))
- *p++ = 0;
-
- if (*objpath != '[' && !IsNum(objpath)) {
- // objpass is a key
+ for (p = objpath; jsp && p; p = (p2 ? p2 : NULL)) {
+ a = (p1 != NULL);
+ p1 = strchr(p, '[');
+ p2 = strchr(p, '.');
+
+ if (!p2)
+ p2 = p1;
+ else if (p1) {
+ if (p1 < p2)
+ p2 = p1;
+ else if (p1 == p2 + 1)
+ *p2++ = 0; // Old syntax .[
+ else
+ p1 = NULL;
+
+ } // endif p1
+
+ if (p2)
+ *p2++ = 0;
+
+ if (!a && *p && *p != '[' && !IsNum(p)) {
+ // obj is a key
if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Table path does not match the json file");
return RC_FX;
} // endif Type
- key = objpath;
+ key = p;
objp = jsp->GetObject();
arp = NULL;
val = objp->GetValue(key);
@@ -2055,15 +2083,15 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} // endif val
} else {
- if (*objpath == '[') {
+ if (*p == '[') {
// Old style
- if (objpath[strlen(objpath) - 1] != ']') {
- sprintf(g->Message, "Invalid Table path %s", Objname);
+ if (p[strlen(p) - 1] != ']') {
+ sprintf(g->Message, "Invalid Table path near %s", p);
return RC_FX;
} else
- objpath++;
+ p++;
- } // endif objpath
+ } // endif p
if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Table path does not match the json file");
@@ -2072,7 +2100,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
arp = jsp->GetArray();
objp = NULL;
- i = atoi(objpath) - B;
+ i = atoi(p) - B;
val = arp->GetValue(i);
if (!val) {
@@ -2083,7 +2111,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} // endif
jsp = val->GetJson();
- } // endfor objpath
+ } // endfor p
} // endif objpath
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 8c3f1013919..88aa5e2ee8b 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -68,8 +68,8 @@ public:
PCSZ sep;
char colname[65], fmt[129], buf[16];
uint *length;
- int i, n, bf, ncol, lvl;
- bool all;
+ int i, n, bf, ncol, lvl, sz;
+ bool all, strfy;
}; // end of JSONDISC
/***********************************************************************/
diff --git a/storage/connect/tabrest.cpp b/storage/connect/tabrest.cpp
index 3ef2a460b9d..b1bdeffc880 100644
--- a/storage/connect/tabrest.cpp
+++ b/storage/connect/tabrest.cpp
@@ -158,16 +158,32 @@ PQRYRES __stdcall ColREST(PGLOBAL g, PTOS tp, char *tab, char *db, bool info)
http = GetStringTableOption(g, tp, "Http", NULL);
uri = GetStringTableOption(g, tp, "Uri", NULL);
- fn = GetStringTableOption(g, tp, "Filename", "rest.json");
#if defined(MARIADB)
ftype = GetStringTableOption(g, tp, "Type", "JSON");
#else // !MARIADB
// OEM tables must specify the file type
ftype = GetStringTableOption(g, tp, "Ftype", "JSON");
#endif // !MARIADB
+ fn = GetStringTableOption(g, tp, "Filename", NULL);
+
+ if (!fn) {
+ int n, m = strlen(ftype) + 1;
+
+ strcat(strcpy(filename, tab), ".");
+ n = strlen(filename);
+
+ // Fold ftype to lower case
+ for (int i = 0; i < m; i++)
+ filename[n + i] = tolower(ftype[i]);
+
+ fn = filename;
+ tp->filename = PlugDup(g, fn);
+ } // endif fn
// We used the file name relative to recorded datapath
- snprintf(filename, sizeof filename, IF_WIN(".\\%s\\%s","./%s/%s"), db, fn);
+ PlugSetPath(filename, fn, db);
+ //strcat(strcat(strcat(strcpy(filename, "."), slash), db), slash);
+ //strncat(filename, fn, _MAX_PATH - strlen(filename));
// Retrieve the file from the web and copy it locally
if (http && grf(g->Message, trace(515), http, uri, filename)) {
@@ -226,12 +242,10 @@ bool RESTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Http = GetStringCatInfo(g, "Http", NULL);
Uri = GetStringCatInfo(g, "Uri", NULL);
- Fn = GetStringCatInfo(g, "Filename", "rest.json");
+ Fn = GetStringCatInfo(g, "Filename", NULL);
// We used the file name relative to recorded datapath
- //PlugSetPath(filename, Fn, GetPath());
- strcpy(filename, GetPath());
- strncat(filename, Fn, _MAX_PATH - strlen(filename));
+ PlugSetPath(filename, Fn, GetPath());
// Retrieve the file from the web and copy it locally
rc = grf(g->Message, xt, Http, Uri, filename);
@@ -269,7 +283,7 @@ PTDB RESTDEF::GetTable(PGLOBAL g, MODE m)
if (trace(515))
htrc("REST GetTable mode=%d\n", m);
- if (m != MODE_READ && m != MODE_READX) {
+ if (m != MODE_READ && m != MODE_READX && m != MODE_ANY) {
strcpy(g->Message, "REST tables are currently read only");
return NULL;
} // endif m
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index b6260eb66ee..81c19ff1a4f 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -3,7 +3,7 @@
/* ------------- */
/* Version 3.0 */
/* */
-/* Author Olivier BERTRAND 2007 - 2017 */
+/* Author Olivier BERTRAND 2007 - 2020 */
/* */
/* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/
@@ -62,6 +62,8 @@ extern "C" char version[];
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define XLEN(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
+int GetDefaultDepth(void);
+
/***********************************************************************/
/* Class and structure used by XMLColumns. */
/***********************************************************************/
@@ -149,8 +151,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
strcpy(g->Message, MSG(MISSING_FNAME));
return NULL;
} else {
- lvl = GetIntegerTableOption(g, topt, "Level", 0);
- lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
+ lvl = GetIntegerTableOption(g, topt, "Level", GetDefaultDepth());
+ lvl = GetIntegerTableOption(g, topt, "Depth", lvl);
+ lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
} // endif fn
if (trace(1))
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index 8abd33079d6..a7e6b53b8ce 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -28,7 +28,7 @@
*/
/****************************************************************************/
-/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2015 */
+/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2020 */
/****************************************************************************/
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
@@ -58,8 +58,8 @@ PCONNECT user_connect::to_users= NULL;
/****************************************************************************/
/* Get the work_size SESSION variable value . */
/****************************************************************************/
-uint GetWorkSize(void);
-void SetWorkSize(uint);
+size_t GetWorkSize(void);
+void SetWorkSize(size_t);
/* -------------------------- class user_connect -------------------------- */
@@ -97,14 +97,14 @@ user_connect::~user_connect()
bool user_connect::user_init()
{
// Initialize Plug-like environment
- uint worksize= GetWorkSize();
+ size_t worksize= GetWorkSize();
PACTIVITY ap= NULL;
PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable
//g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
- g= PlugInit(NULL, worksize);
+ g= PlugInit(NULL, (size_t)worksize);
// Check whether the initialization is complete
if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size)
@@ -157,16 +157,17 @@ void user_connect::SetHandler(ha_connect *hc)
bool user_connect::CheckCleanup(bool force)
{
if (thdp->query_id > last_query_id || force) {
- uint worksize= GetWorkSize(), size = g->Sarea_Size;
+ size_t worksize = GetWorkSize();
PlugCleanup(g, true);
- if (size != worksize) {
+ if (worksize != g->Sarea_Size) {
FreeSarea(g);
+ g->Saved_Size = g->Sarea_Size;
// Check whether the work area could be allocated
if (AllocSarea(g, worksize)) {
- AllocSarea(g, size);
+ AllocSarea(g, g->Saved_Size);
SetWorkSize(g->Sarea_Size); // Was too big
} // endif sarea
@@ -174,10 +175,11 @@ bool user_connect::CheckCleanup(bool force)
PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
- g->Createas = 0;
+ g->Createas = false;
g->Alchecked = 0;
g->Mrr = 0;
g->More = 0;
+ g->Saved_Size = 0;
last_query_id= thdp->query_id;
if (trace(65) && !force)
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 2fad67f453b..5951b26e81e 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -2251,6 +2251,15 @@ void BINVAL::SetBinValue(void *p)
} // end of SetBinValue
/***********************************************************************/
+/* BINVAL SetBinValue: fill string with len bytes. */
+/***********************************************************************/
+void BINVAL::SetBinValue(void* p, ulong len)
+{
+ memcpy(Binp, p, len);
+ Len = len;
+} // end of SetBinValue
+
+/***********************************************************************/
/* GetBinValue: fill a buffer with the internal binary value. */
/* This function checks whether the buffer length is enough and */
/* returns true if not. Actual filling occurs only if go is true. */
diff --git a/storage/connect/value.h b/storage/connect/value.h
index 4f7d9a440fa..ee7a1c8032f 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -115,8 +115,8 @@ class DllExport VALUE : public BLOCK {
virtual void SetValue(ulonglong) {assert(false);}
virtual void SetValue(double) {assert(false);}
virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
- virtual void SetBinValue(void *p) = 0;
- virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
+ virtual void SetBinValue(void* p) = 0;
+ virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
virtual int ShowValue(char *buf, int len) = 0;
virtual char *GetCharString(char *p) = 0;
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
@@ -385,7 +385,8 @@ class DllExport BINVAL: public VALUE {
virtual void SetValue(ulonglong n);
virtual void SetValue(double f);
virtual void SetBinValue(void *p);
- virtual bool GetBinValue(void *buf, int buflen, bool go);
+ virtual void SetBinValue(void* p, ulong len);
+ virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual int CompareValue(PVAL) {assert(false); return 0;}
virtual int ShowValue(char *buf, int len);
virtual char *GetCharString(char *p);
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 895b6edfcf2..96f4f4dc53a 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -26,12 +26,8 @@
#include "ha_heap.h"
#include "sql_base.h"
-static handler *heap_create_handler(handlerton *hton,
- TABLE_SHARE *table,
- MEM_ROOT *mem_root);
-static int
-heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
- HP_CREATE_INFO *hp_create_info);
+static handler *heap_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
+static int heap_prepare_hp_create_info(TABLE *, bool, HP_CREATE_INFO *);
static int heap_panic(handlerton *hton, ha_panic_function flag)
@@ -157,7 +153,7 @@ int ha_heap::close(void)
handler *ha_heap::clone(const char *name, MEM_ROOT *mem_root)
{
- handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
+ handler *new_handler= get_new_handler(table->s, mem_root, ht);
if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED))
return new_handler;
@@ -371,8 +367,8 @@ int ha_heap::info(uint flag)
{
HEAPINFO hp_info;
- if (!table)
- return 1;
+ if (!file)
+ return 0;
(void) heap_info(file,&hp_info,flag);
@@ -606,16 +602,15 @@ ha_rows ha_heap::records_in_range(uint inx, const key_range *min_key,
}
-static int
-heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
- HP_CREATE_INFO *hp_create_info)
+static int heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
+ HP_CREATE_INFO *hp_create_info)
{
- uint key, parts, mem_per_row= 0, keys= table_arg->s->keys;
+ TABLE_SHARE *share= table_arg->s;
+ uint key, parts, mem_per_row= 0, keys= share->keys;
uint auto_key= 0, auto_key_type= 0;
ha_rows max_rows;
HP_KEYDEF *keydef;
HA_KEYSEG *seg;
- TABLE_SHARE *share= table_arg->s;
bool found_real_auto_increment= 0;
bzero(hp_create_info, sizeof(*hp_create_info));
@@ -623,12 +618,12 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
for (key= parts= 0; key < keys; key++)
parts+= table_arg->key_info[key].user_defined_key_parts;
- if (!(keydef= (HP_KEYDEF*) my_malloc(hp_key_memory_HP_KEYDEF,
- keys * sizeof(HP_KEYDEF) +
- parts * sizeof(HA_KEYSEG),
- MYF(MY_WME | MY_THREAD_SPECIFIC))))
+ if (!my_multi_malloc(hp_key_memory_HP_KEYDEF,
+ MYF(MY_WME | MY_THREAD_SPECIFIC),
+ &keydef, keys * sizeof(HP_KEYDEF),
+ &seg, parts * sizeof(HA_KEYSEG),
+ NULL))
return my_errno;
- seg= reinterpret_cast<HA_KEYSEG*>(keydef + keys);
for (key= 0; key < keys; key++)
{
KEY *pos= table_arg->key_info+key;
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 4fac94d211e..b7e7fb93bf3 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -1,3 +1,4 @@
+
# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2020, MariaDB Corporation.
#
@@ -28,6 +29,7 @@ SET(INNOBASE_SOURCES
btr/btr0pcur.cc
btr/btr0sea.cc
btr/btr0defragment.cc
+ buf/buf0block_hint.cc
buf/buf0buddy.cc
buf/buf0buf.cc
buf/buf0dblwr.cc
@@ -186,7 +188,6 @@ SET(INNOBASE_SOURCES
include/mtr0mtr.h
include/mtr0mtr.ic
include/mtr0types.h
- include/os0api.h
include/os0event.h
include/os0file.h
include/os0file.ic
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 8ed25db8cb7..b2de0ad33b2 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -55,7 +55,7 @@ bool
btr_can_merge_with_page(
/*====================*/
btr_cur_t* cursor, /*!< in: cursor on the page to merge */
- ulint page_no, /*!< in: a sibling page */
+ uint32_t page_no, /*!< in: a sibling page */
buf_block_t** merge_block, /*!< out: the merge block */
mtr_t* mtr); /*!< in: mini-transaction */
@@ -280,7 +280,7 @@ the index.
ulint
btr_height_get(
/*===========*/
- dict_index_t* index, /*!< in: index tree */
+ const dict_index_t* index, /*!< in: index tree */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint height=0;
@@ -511,7 +511,7 @@ buf_block_t*
btr_page_alloc_low(
/*===============*/
dict_index_t* index, /*!< in: index */
- ulint hint_page_no, /*!< in: hint of a good page */
+ uint32_t hint_page_no, /*!< in: hint of a good page */
byte file_direction, /*!< in: direction where a possible
page split is made */
ulint level, /*!< in: level where the page is placed
@@ -548,7 +548,7 @@ buf_block_t*
btr_page_alloc(
/*===========*/
dict_index_t* index, /*!< in: index */
- ulint hint_page_no, /*!< in: hint of a good page */
+ uint32_t hint_page_no, /*!< in: hint of a good page */
byte file_direction, /*!< in: direction where a possible
page split is made */
ulint level, /*!< in: level where the page is placed
@@ -582,7 +582,7 @@ Gets the number of pages in a B-tree.
ulint
btr_get_size(
/*=========*/
- dict_index_t* index, /*!< in: index */
+ const dict_index_t* index, /*!< in: index */
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
@@ -1049,7 +1049,7 @@ btr_create(
return(FIL_NULL);
}
- ut_ad(block->page.id().page_no() == IBUF_TREE_ROOT_PAGE_NO);
+ ut_ad(block->page.id() == page_id_t(0,IBUF_TREE_ROOT_PAGE_NO));
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
@@ -2801,7 +2801,7 @@ func_start:
tuple to be inserted should be the first record on the upper
half-page */
bool insert_left = false;
- ulint hint_page_no = block->page.id().page_no() + 1;
+ uint32_t hint_page_no = block->page.id().page_no() + 1;
byte direction = FSP_UP;
if (tuple && n_iterations > 0) {
@@ -3386,8 +3386,6 @@ btr_compress(
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
- ulint left_page_no;
- ulint right_page_no;
buf_block_t* merge_block;
page_t* merge_page = NULL;
page_zip_des_t* merge_page_zip;
@@ -3416,8 +3414,8 @@ btr_compress(
MONITOR_INC(MONITOR_INDEX_MERGE_ATTEMPTS);
- left_page_no = btr_page_get_prev(page);
- right_page_no = btr_page_get_next(page);
+ const uint32_t left_page_no = btr_page_get_prev(page);
+ const uint32_t right_page_no = btr_page_get_next(page);
#ifdef UNIV_DEBUG
if (!page_is_leaf(page) && left_page_no == FIL_NULL) {
@@ -3989,8 +3987,6 @@ btr_discard_page(
mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
- ulint left_page_no;
- ulint right_page_no;
buf_block_t* merge_block;
buf_block_t* block;
btr_cur_t parent_cursor;
@@ -4014,8 +4010,8 @@ btr_discard_page(
/* Decide the page which will inherit the locks */
- left_page_no = btr_page_get_prev(block->frame);
- right_page_no = btr_page_get_next(block->frame);
+ const uint32_t left_page_no = btr_page_get_prev(block->frame);
+ const uint32_t right_page_no = btr_page_get_next(block->frame);
ut_d(bool parent_is_different = false);
if (left_page_no != FIL_NULL) {
@@ -4598,8 +4594,6 @@ btr_validate_level(
btr_cur_t node_cur;
btr_cur_t right_node_cur;
rec_t* rec;
- ulint right_page_no;
- ulint left_page_no;
page_cur_t cursor;
dtuple_t* node_ptr_tuple;
bool ret = true;
@@ -4612,8 +4606,8 @@ btr_validate_level(
#endif /* UNIV_ZIP_DEBUG */
ulint savepoint = 0;
ulint savepoint2 = 0;
- ulint parent_page_no = FIL_NULL;
- ulint parent_right_page_no = FIL_NULL;
+ uint32_t parent_page_no = FIL_NULL;
+ uint32_t parent_right_page_no = FIL_NULL;
bool rightmost_child = false;
mtr.start();
@@ -4669,7 +4663,7 @@ btr_validate_level(
does not use such scan for any of its DML or query
operations */
if (dict_index_is_spatial(index)) {
- left_page_no = btr_page_get_prev(page);
+ uint32_t left_page_no = btr_page_get_prev(page);
while (left_page_no != FIL_NULL) {
/* To obey latch order of tree blocks,
@@ -4738,8 +4732,8 @@ loop:
ut_a(btr_page_get_level(page) == level);
- right_page_no = btr_page_get_next(page);
- left_page_no = btr_page_get_prev(page);
+ uint32_t right_page_no = btr_page_get_next(page);
+ uint32_t left_page_no = btr_page_get_prev(page);
ut_a(!page_is_empty(page)
|| (level == 0
@@ -4860,8 +4854,7 @@ loop:
rec = btr_cur_get_rec(&node_cur);
fprintf(stderr, "\n"
- "InnoDB: node ptr child page n:o "
- ULINTPF "\n",
+ "InnoDB: node ptr child page n:o %u\n",
btr_node_ptr_get_child_page_no(rec, offsets));
fputs("InnoDB: record on page ", stderr);
@@ -5096,7 +5089,7 @@ bool
btr_can_merge_with_page(
/*====================*/
btr_cur_t* cursor, /*!< in: cursor on the page to merge */
- ulint page_no, /*!< in: a sibling page */
+ uint32_t page_no, /*!< in: a sibling page */
buf_block_t** merge_block, /*!< out: the merge block */
mtr_t* mtr) /*!< in: mini-transaction */
{
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index a44b96add2c..6e8b88172e8 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -43,7 +43,6 @@ PageBulk::init()
{
buf_block_t* new_block;
page_t* new_page;
- ulint new_page_no;
ut_ad(m_heap == NULL);
m_heap = mem_heap_create(1000);
@@ -61,12 +60,10 @@ PageBulk::init()
alloc_mtr.start();
m_index->set_modified(alloc_mtr);
- ulint n_reserved;
- bool success;
- success = fsp_reserve_free_extents(&n_reserved,
- m_index->table->space,
- 1, FSP_NORMAL, &alloc_mtr);
- if (!success) {
+ uint32_t n_reserved;
+ if (!fsp_reserve_free_extents(&n_reserved,
+ m_index->table->space,
+ 1, FSP_NORMAL, &alloc_mtr)) {
alloc_mtr.commit();
m_mtr.commit();
return(DB_OUT_OF_FILE_SPACE);
@@ -81,7 +78,7 @@ PageBulk::init()
alloc_mtr.commit();
new_page = buf_block_get_frame(new_block);
- new_page_no = page_get_page_no(new_page);
+ m_page_no = new_block->page.id().page_no();
byte* index_id = my_assume_aligned<2>
(PAGE_HEADER + PAGE_INDEX_ID + new_page);
@@ -108,8 +105,7 @@ PageBulk::init()
false, &m_mtr);
new_page = buf_block_get_frame(new_block);
- new_page_no = page_get_page_no(new_page);
- ut_ad(m_page_no == new_page_no);
+ ut_ad(new_block->page.id().page_no() == m_page_no);
ut_ad(page_dir_get_n_heap(new_page) == PAGE_HEAP_NO_USER_LOW);
@@ -125,7 +121,6 @@ PageBulk::init()
m_block = new_block;
m_page = new_page;
- m_page_no = new_page_no;
m_cur_rec = page_get_infimum_rec(new_page);
ut_ad(m_is_comp == !!page_is_comp(new_page));
m_free_space = page_get_free_space_of_empty(m_is_comp);
@@ -854,6 +849,8 @@ PageBulk::latch()
m_mtr.start();
m_index->set_modified(m_mtr);
+ ut_ad(m_block->page.buf_fix_count());
+
/* In case the block is S-latched by page_cleaner. */
if (!buf_page_optimistic_get(RW_X_LATCH, m_block, m_modify_clock,
__FILE__, __LINE__, &m_mtr)) {
@@ -872,6 +869,8 @@ PageBulk::latch()
buf_block_buf_fix_dec(m_block);
+ ut_ad(m_block->page.buf_fix_count());
+
ut_ad(m_cur_rec > m_page && m_cur_rec < m_heap_top);
return (m_err);
@@ -981,7 +980,7 @@ inline void BtrBulk::logFreeCheck()
if (log_sys.check_flush_or_checkpoint()) {
release();
- log_free_check();
+ log_check_margins();
latch();
}
@@ -1111,13 +1110,9 @@ BtrBulk::insert(
goto func_exit;
}
- /* Wake up page cleaner to flush dirty pages. */
srv_inc_activity_count();
- os_event_set(buf_flush_event);
-
logFreeCheck();
}
-
}
/* Convert tuple to rec. */
@@ -1163,7 +1158,7 @@ if no error occurs.
dberr_t
BtrBulk::finish(dberr_t err)
{
- ulint last_page_no = FIL_NULL;
+ uint32_t last_page_no = FIL_NULL;
ut_ad(!m_index->table->is_temporary());
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index a190c11eb0a..846d8ecfd7e 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -770,36 +770,31 @@ btr_cur_optimistic_latch_leaves(
unsigned line,
mtr_t* mtr)
{
- rw_lock_type_t mode;
- ulint left_page_no;
- ulint curr_page_no;
+ ut_ad(block->page.buf_fix_count());
+ ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
switch (*latch_mode) {
+ default:
+ ut_error;
+ return(false);
case BTR_SEARCH_LEAF:
case BTR_MODIFY_LEAF:
return(buf_page_optimistic_get(*latch_mode, block,
modify_clock, file, line, mtr));
case BTR_SEARCH_PREV:
case BTR_MODIFY_PREV:
- mode = *latch_mode == BTR_SEARCH_PREV
- ? RW_S_LATCH : RW_X_LATCH;
-
- if (block->page.state() != BUF_BLOCK_FILE_PAGE) {
- return(false);
- }
- /* pin the block not to be relocated */
- buf_block_buf_fix_inc(block, file, line);
-
rw_lock_s_lock(&block->lock);
if (block->modify_clock != modify_clock) {
rw_lock_s_unlock(&block->lock);
-
- goto unpin_failed;
+ return false;
}
- curr_page_no = block->page.id().page_no();
- left_page_no = btr_page_get_prev(block->frame);
+ const uint32_t curr_page_no = block->page.id().page_no();
+ const uint32_t left_page_no = btr_page_get_prev(block->frame);
rw_lock_s_unlock(&block->lock);
+ const rw_lock_type_t mode = *latch_mode == BTR_SEARCH_PREV
+ ? RW_S_LATCH : RW_X_LATCH;
+
if (left_page_no != FIL_NULL) {
dberr_t err = DB_SUCCESS;
cursor->left_block = buf_page_get_gen(
@@ -818,7 +813,7 @@ btr_cur_optimistic_latch_leaves(
/* release the left block */
btr_leaf_page_release(
cursor->left_block, mode, mtr);
- goto unpin_failed;
+ return false;
}
} else {
cursor->left_block = NULL;
@@ -827,29 +822,30 @@ btr_cur_optimistic_latch_leaves(
if (buf_page_optimistic_get(mode, block, modify_clock,
file, line, mtr)) {
if (btr_page_get_prev(block->frame) == left_page_no) {
- buf_block_buf_fix_dec(block);
+ /* block was already buffer-fixed while
+ entering the function and
+ buf_page_optimistic_get() buffer-fixes
+ it again. */
+ ut_ad(2 <= block->page.buf_fix_count());
*latch_mode = mode;
return(true);
} else {
- /* release the block */
+ /* release the block and decrement of
+ buf_fix_count which was incremented
+ in buf_page_optimistic_get() */
btr_leaf_page_release(block, mode, mtr);
}
}
+ ut_ad(block->page.buf_fix_count());
/* release the left block */
if (cursor->left_block != NULL) {
btr_leaf_page_release(cursor->left_block,
mode, mtr);
}
-unpin_failed:
- /* unpin the block */
- buf_block_buf_fix_dec(block);
- return(false);
-
- default:
- ut_error;
- return(false);
}
+
+ return false;
}
/**
@@ -1403,12 +1399,7 @@ btr_cur_search_to_nth_level_func(
guess = NULL;
#else
info = btr_search_get_info(index);
-
- if (!buf_pool.is_obsolete(info->withdraw_clock)) {
- guess = info->root_guess;
- } else {
- guess = NULL;
- }
+ guess = info->root_guess;
#ifdef BTR_CUR_HASH_ADAPT
@@ -1713,7 +1704,7 @@ retry_page_get:
if (retrying_for_search_prev && height != 0) {
/* also latch left sibling */
- ulint left_page_no;
+ uint32_t left_page_no;
buf_block_t* get_block;
ut_ad(rw_latch == RW_NO_LATCH);
@@ -1842,10 +1833,7 @@ retry_page_get:
}
#ifdef BTR_CUR_ADAPT
- if (block != guess) {
- info->root_guess = block;
- info->withdraw_clock = buf_pool.withdraw_clock();
- }
+ info->root_guess = block;
#endif
}
@@ -3310,20 +3298,29 @@ upd_sys:
/**
Prefetch siblings of the leaf for the pessimistic operation.
-@param block leaf page */
-static void btr_cur_prefetch_siblings(const buf_block_t* block)
+@param block leaf page
+@param index index of the page */
+static void btr_cur_prefetch_siblings(const buf_block_t *block,
+ const dict_index_t *index)
{
- const page_t *page= block->frame;
- ut_ad(page_is_leaf(page));
+ ut_ad(page_is_leaf(block->frame));
+ if (index->is_ibuf())
+ return;
+
+ const page_t *page= block->frame;
uint32_t prev= mach_read_from_4(my_assume_aligned<4>(page + FIL_PAGE_PREV));
uint32_t next= mach_read_from_4(my_assume_aligned<4>(page + FIL_PAGE_NEXT));
- if (prev != FIL_NULL)
- buf_read_page_background(page_id_t(block->page.id().space(), prev),
+ if (prev == FIL_NULL);
+ else if (index->table->space->acquire())
+ buf_read_page_background(index->table->space,
+ page_id_t(block->page.id().space(), prev),
block->zip_size(), false);
- if (next != FIL_NULL)
- buf_read_page_background(page_id_t(block->page.id().space(), next),
+ if (next == FIL_NULL);
+ else if (index->table->space->acquire())
+ buf_read_page_background(index->table->space,
+ page_id_t(block->page.id().space(), next),
block->zip_size(), false);
}
@@ -3442,8 +3439,8 @@ fail:
/* prefetch siblings of the leaf for the pessimistic
operation, if the page is leaf. */
- if (page_is_leaf(page) && !index->is_ibuf()) {
- btr_cur_prefetch_siblings(block);
+ if (page_is_leaf(page)) {
+ btr_cur_prefetch_siblings(block, index);
}
fail_err:
@@ -3672,7 +3669,7 @@ btr_cur_pessimistic_insert(
dberr_t err;
bool inherit = false;
bool success;
- ulint n_reserved = 0;
+ uint32_t n_reserved = 0;
ut_ad(dtuple_check_typed(entry));
ut_ad(thr || !(~flags & (BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG)));
@@ -3704,7 +3701,7 @@ btr_cur_pessimistic_insert(
of the index tree, so that the insert will not fail because
of lack of space */
- ulint n_extents = cursor->tree_height / 16 + 3;
+ uint32_t n_extents = uint32_t(cursor->tree_height / 16 + 3);
success = fsp_reserve_free_extents(&n_reserved,
index->table->space,
@@ -4581,7 +4578,7 @@ any_extern:
/* prefetch siblings of the leaf for the pessimistic
operation. */
- btr_cur_prefetch_siblings(block);
+ btr_cur_prefetch_siblings(block, index);
return(DB_OVERFLOW);
}
@@ -4772,10 +4769,10 @@ func_exit:
}
}
- if (err != DB_SUCCESS && !index->is_ibuf()) {
+ if (err != DB_SUCCESS) {
/* prefetch siblings of the leaf for the pessimistic
operation. */
- btr_cur_prefetch_siblings(block);
+ btr_cur_prefetch_siblings(block, index);
}
return(err);
@@ -4871,8 +4868,8 @@ btr_cur_pessimistic_update(
dberr_t err;
dberr_t optim_err;
roll_ptr_t roll_ptr;
- ibool was_first;
- ulint n_reserved = 0;
+ bool was_first;
+ uint32_t n_reserved = 0;
*offsets = NULL;
*big_rec = NULL;
@@ -5034,7 +5031,7 @@ btr_cur_pessimistic_update(
of the index tree, so that the update will not fail because
of lack of space */
- ulint n_extents = cursor->tree_height / 16 + 3;
+ uint32_t n_extents = uint32_t(cursor->tree_height / 16 + 3);
if (!fsp_reserve_free_extents(
&n_reserved, index->table->space, n_extents,
@@ -5457,7 +5454,6 @@ btr_cur_optimistic_delete_func(
mem_heap_t* heap = NULL;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs* offsets = offsets_;
- ibool no_compress_needed;
rec_offs_init(offsets_);
ut_ad(flags == 0 || flags == BTR_CREATE_FLAG);
@@ -5478,6 +5474,20 @@ btr_cur_optimistic_delete_func(
rec = btr_cur_get_rec(cursor);
+ offsets = rec_get_offsets(rec, cursor->index, offsets, true,
+ ULINT_UNDEFINED, &heap);
+
+ const ibool no_compress_needed = !rec_offs_any_extern(offsets)
+ && btr_cur_can_delete_without_compress(
+ cursor, rec_offs_size(offsets), mtr);
+
+ if (!no_compress_needed) {
+ /* prefetch siblings of the leaf for the pessimistic
+ operation. */
+ btr_cur_prefetch_siblings(block, cursor->index);
+ goto func_exit;
+ }
+
if (UNIV_UNLIKELY(block->page.id().page_no() == cursor->index->page
&& page_get_n_recs(block->frame) == 1
+ (cursor->index->is_instant()
@@ -5515,19 +5525,11 @@ btr_cur_optimistic_delete_func(
}
page_cur_set_after_last(block,
btr_cur_get_page_cur(cursor));
- return true;
+ goto func_exit;
}
}
- offsets = rec_get_offsets(rec, cursor->index, offsets, true,
- ULINT_UNDEFINED, &heap);
-
- no_compress_needed = !rec_offs_any_extern(offsets)
- && btr_cur_can_delete_without_compress(
- cursor, rec_offs_size(offsets), mtr);
-
- if (no_compress_needed) {
-
+ {
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip= buf_block_get_page_zip(block);
@@ -5587,10 +5589,6 @@ btr_cur_optimistic_delete_func(
ibuf_update_free_bits_low(block, max_ins, mtr);
}
}
- } else {
- /* prefetch siblings of the leaf for the pessimistic
- operation. */
- btr_cur_prefetch_siblings(block);
}
func_exit:
@@ -5635,7 +5633,7 @@ btr_cur_pessimistic_delete(
page_zip_des_t* page_zip;
dict_index_t* index;
rec_t* rec;
- ulint n_reserved = 0;
+ uint32_t n_reserved = 0;
bool success;
ibool ret = FALSE;
mem_heap_t* heap;
@@ -5664,7 +5662,7 @@ btr_cur_pessimistic_delete(
of the index tree, so that the node pointer updates will
not fail because of lack of space */
- ulint n_extents = cursor->tree_height / 32 + 1;
+ uint32_t n_extents = uint32_t(cursor->tree_height / 32 + 1);
success = fsp_reserve_free_extents(&n_reserved,
index->table->space,
@@ -6557,21 +6555,19 @@ btr_record_not_null_field_in_rec(
}
}
-/*******************************************************************//**
-Estimates the number of different key values in a given index, for
+/** Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals[] (indexed
0..n_uniq-1) and the number of pages that were sampled is saved in
-index->stat_n_sample_sizes[].
+result.n_sample_sizes[].
If innodb_stats_method is nulls_ignored, we also record the number of
non-null values for each prefix and stored the estimates in
-array index->stat_n_non_null_key_vals.
-@return true if the index is available and we get the estimated numbers,
-false if the index is unavailable. */
-bool
-btr_estimate_number_of_different_key_vals(
-/*======================================*/
- dict_index_t* index) /*!< in: index */
+array result.n_non_null_key_vals.
+@param[in] index index
+@return vector with statistics information
+empty vector if the index is unavailable. */
+std::vector<index_field_stats_t>
+btr_estimate_number_of_different_key_vals(dict_index_t* index)
{
btr_cur_t cursor;
page_t* page;
@@ -6591,11 +6587,11 @@ btr_estimate_number_of_different_key_vals(
rec_offs* offsets_rec = NULL;
rec_offs* offsets_next_rec = NULL;
+ std::vector<index_field_stats_t> result;
+
/* For spatial index, there is no such stats can be
fetched. */
- if (dict_index_is_spatial(index)) {
- return(false);
- }
+ ut_ad(!dict_index_is_spatial(index));
n_cols = dict_index_get_n_unique(index);
@@ -6705,7 +6701,7 @@ btr_estimate_number_of_different_key_vals(
mtr_commit(&mtr);
mem_heap_free(heap);
- return(false);
+ return result;
}
/* Count the number of different key values for each prefix of
@@ -6811,8 +6807,12 @@ exit_loop:
also the pages used for external storage of fields (those pages are
included in index->stat_n_leaf_pages) */
+ result.reserve(n_cols);
+
for (j = 0; j < n_cols; j++) {
- index->stat_n_diff_key_vals[j]
+ index_field_stats_t stat;
+
+ stat.n_diff_key_vals
= BTR_TABLE_STATS_FROM_SAMPLE(
n_diff[j], index, n_sample_pages,
total_external_size, not_empty_flag);
@@ -6833,25 +6833,23 @@ exit_loop:
add_on = n_sample_pages;
}
- index->stat_n_diff_key_vals[j] += add_on;
+ stat.n_diff_key_vals += add_on;
- index->stat_n_sample_sizes[j] = n_sample_pages;
+ stat.n_sample_sizes = n_sample_pages;
- /* Update the stat_n_non_null_key_vals[] with our
- sampled result. stat_n_non_null_key_vals[] is created
- and initialized to zero in dict_index_add_to_cache(),
- along with stat_n_diff_key_vals[] array */
if (n_not_null != NULL) {
- index->stat_n_non_null_key_vals[j] =
+ stat.n_non_null_key_vals =
BTR_TABLE_STATS_FROM_SAMPLE(
n_not_null[j], index, n_sample_pages,
total_external_size, not_empty_flag);
}
+
+ result.push_back(stat);
}
mem_heap_free(heap);
- return(true);
+ return result;
}
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
@@ -7026,7 +7024,7 @@ btr_cur_unmark_extern_fields(
Returns the length of a BLOB part stored on the header page.
@return part length */
static
-ulint
+uint32_t
btr_blob_get_part_len(
/*==================*/
const byte* blob_header) /*!< in: blob header */
@@ -7038,7 +7036,7 @@ btr_blob_get_part_len(
Returns the page number where the next BLOB part is stored.
@return page number or FIL_NULL if no more pages */
static
-ulint
+uint32_t
btr_blob_get_next_page_no(
/*======================*/
const byte* blob_header) /*!< in: blob header */
@@ -7058,7 +7056,7 @@ static void btr_blob_free(buf_block_t *block, bool all, mtr_t *mtr)
const ulint fold= page_id.fold();
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (buf_page_t *bpage= buf_pool.page_hash_get_low(page_id, fold))
if(!buf_LRU_free_page(bpage, all) && all && bpage->zip.data)
@@ -7066,7 +7064,7 @@ static void btr_blob_free(buf_block_t *block, bool all, mtr_t *mtr)
if the whole ROW_FORMAT=COMPRESSED block cannot be deallocted. */
buf_LRU_free_page(bpage, false);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/** Helper class used while writing blob pages, during insert or update. */
@@ -7118,12 +7116,13 @@ struct btr_blob_log_check_t {
{
dict_index_t* index = m_pcur->index();
ulint offs = 0;
- ulint page_no = ULINT_UNDEFINED;
+ uint32_t page_no = FIL_NULL;
if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) {
offs = page_offset(*m_rec);
page_no = (*m_block)->page.id().page_no();
buf_block_buf_fix_inc(*m_block, __FILE__, __LINE__);
+ ut_ad(page_no != FIL_NULL);
} else {
btr_pcur_store_position(m_pcur, m_mtr);
}
@@ -7140,7 +7139,7 @@ struct btr_blob_log_check_t {
m_mtr->set_log_mode(log_mode);
index->set_modified(*m_mtr);
- if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) {
+ if (UNIV_UNLIKELY(page_no != FIL_NULL)) {
m_pcur->btr_cur.page_cur.block = btr_block_get(
*index, page_no, RW_X_LATCH, false, m_mtr);
m_pcur->btr_cur.page_cur.rec
@@ -7203,14 +7202,10 @@ btr_store_big_rec_extern_fields(
committed and restarted. */
enum blob_op op) /*! in: operation code */
{
- ulint rec_page_no;
byte* field_ref;
ulint extern_len;
ulint store_len;
- ulint page_no;
ulint space_id;
- ulint prev_page_no;
- ulint hint_page_no;
ulint i;
mtr_t mtr;
mem_heap_t* heap = NULL;
@@ -7234,7 +7229,6 @@ btr_store_big_rec_extern_fields(
&rec, op);
page_zip = buf_block_get_page_zip(rec_block);
space_id = rec_block->page.id().space();
- rec_page_no = rec_block->page.id().page_no();
ut_a(fil_page_index_page_check(page_align(rec))
|| op == BTR_STORE_INSERT_BULK);
@@ -7297,7 +7291,7 @@ btr_store_big_rec_extern_fields(
MEM_CHECK_DEFINED(big_rec_vec->fields[i].data, extern_len);
ut_a(extern_len > 0);
- prev_page_no = FIL_NULL;
+ uint32_t prev_page_no = FIL_NULL;
if (page_zip) {
int err = deflateReset(&c_stream);
@@ -7311,7 +7305,7 @@ btr_store_big_rec_extern_fields(
for (ulint blob_npages = 0;; ++blob_npages) {
buf_block_t* block;
const ulint commit_freq = 4;
- ulint r_extents;
+ uint32_t r_extents;
ut_ad(page_align(field_ref) == page_align(rec));
@@ -7323,7 +7317,6 @@ btr_store_big_rec_extern_fields(
rec, offsets, field_no);
page_zip = buf_block_get_page_zip(rec_block);
- rec_page_no = rec_block->page.id().page_no();
}
mtr.start();
@@ -7333,10 +7326,9 @@ btr_store_big_rec_extern_fields(
buf_page_get(rec_block->page.id(),
rec_block->zip_size(), RW_X_LATCH, &mtr);
- if (prev_page_no == FIL_NULL) {
- hint_page_no = 1 + rec_page_no;
- } else {
- hint_page_no = prev_page_no + 1;
+ uint32_t hint_prev = prev_page_no;
+ if (hint_prev == FIL_NULL) {
+ hint_prev = rec_block->page.id().page_no();
}
if (!fsp_reserve_free_extents(&r_extents,
@@ -7347,14 +7339,14 @@ btr_store_big_rec_extern_fields(
goto func_exit;
}
- block = btr_page_alloc(index, hint_page_no, FSP_NO_DIR,
- 0, &mtr, &mtr);
+ block = btr_page_alloc(index, hint_prev + 1,
+ FSP_NO_DIR, 0, &mtr, &mtr);
index->table->space->release_free_extents(r_extents);
ut_a(block != NULL);
- page_no = block->page.id().page_no();
+ const uint32_t page_no = block->page.id().page_no();
if (prev_page_no != FIL_NULL) {
buf_block_t* prev_block;
@@ -7586,7 +7578,7 @@ static void btr_check_blob_fil_page_type(const buf_block_t& block, bool read)
if (UNIV_LIKELY(type == FIL_PAGE_TYPE_BLOB))
return;
/* FIXME: take the tablespace as a parameter */
- if (fil_space_t *space= fil_space_acquire_silent(block.page.id().space()))
+ if (fil_space_t *space= fil_space_t::get(block.page.id().space()))
{
/* Old versions of InnoDB did not initialize FIL_PAGE_TYPE on BLOB
pages. Do not print anything about the type mismatch when reading
@@ -7632,12 +7624,12 @@ btr_free_externally_stored_field(
X-latch to the index tree */
{
page_t* page;
- const ulint space_id = mach_read_from_4(
+ const uint32_t space_id = mach_read_from_4(
field_ref + BTR_EXTERN_SPACE_ID);
- const ulint start_page = mach_read_from_4(
+ const uint32_t start_page = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
- ulint page_no;
- ulint next_page_no;
+ uint32_t page_no;
+ uint32_t next_page_no;
mtr_t mtr;
ut_ad(index->is_primary());
@@ -7870,10 +7862,9 @@ btr_copy_blob_prefix(
/*=================*/
byte* buf, /*!< out: the externally stored part of
the field, or a prefix of it */
- ulint len, /*!< in: length of buf, in bytes */
- ulint space_id,/*!< in: space id of the BLOB pages */
- ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset) /*!< in: offset on the first BLOB page */
+ uint32_t len, /*!< in: length of buf, in bytes */
+ page_id_t id, /*!< in: page identifier of the first BLOB page */
+ uint32_t offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -7887,8 +7878,7 @@ btr_copy_blob_prefix(
mtr_start(&mtr);
- block = buf_page_get(page_id_t(space_id, page_no),
- 0, RW_S_LATCH, &mtr);
+ block = buf_page_get(id, 0, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
page = buf_block_get_frame(block);
@@ -7902,11 +7892,11 @@ btr_copy_blob_prefix(
blob_header + BTR_BLOB_HDR_SIZE, copy_len);
copied_len += copy_len;
- page_no = btr_blob_get_next_page_no(blob_header);
+ id.set_page_no(btr_blob_get_next_page_no(blob_header));
mtr_commit(&mtr);
- if (page_no == FIL_NULL || copy_len != part_len) {
+ if (id.page_no() == FIL_NULL || copy_len != part_len) {
MEM_CHECK_DEFINED(buf, copied_len);
return(copied_len);
}
@@ -7927,18 +7917,16 @@ by a lock or a page latch.
or a prefix of it
@param[in] len length of buf, in bytes
@param[in] zip_size ROW_FORMAT=COMPRESSED page size
-@param[in] space_id space id of the BLOB pages
-@param[in] offset offset on the first BLOB page
+@param[in] id page identifier of the BLOB pages
@return number of bytes written to buf */
static
ulint
btr_copy_zblob_prefix(
byte* buf,
- ulint len,
+ uint32_t len,
ulint zip_size,
- ulint space_id,
- ulint page_no,
- ulint offset)
+ page_id_t id,
+ uint32_t offset)
{
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
mem_heap_t* heap;
@@ -7957,25 +7945,23 @@ btr_copy_zblob_prefix(
ut_ad(zip_size);
ut_ad(ut_is_2pow(zip_size));
- ut_ad(space_id);
+ ut_ad(id.space());
err = inflateInit(&d_stream);
ut_a(err == Z_OK);
for (;;) {
buf_page_t* bpage;
- ulint next_page_no;
+ uint32_t next_page_no;
/* There is no latch on bpage directly. Instead,
bpage is protected by the B-tree page latch that
is being held on the clustered index record, or,
in row_merge_copy_blobs(), by an exclusive table lock. */
- bpage = buf_page_get_zip(page_id_t(space_id, page_no),
- zip_size);
+ bpage = buf_page_get_zip(id, zip_size);
if (UNIV_UNLIKELY(!bpage)) {
- ib::error() << "Cannot load compressed BLOB "
- << page_id_t(space_id, page_no);
+ ib::error() << "Cannot load compressed BLOB " << id;
goto func_exit;
}
@@ -7984,8 +7970,7 @@ btr_copy_zblob_prefix(
ib::error() << "Unexpected type "
<< fil_page_get_type(bpage->zip.data)
- << " of compressed BLOB page "
- << page_id_t(space_id, page_no);
+ << " of compressed BLOB page " << id;
ut_ad(0);
goto end_of_blob;
@@ -8020,7 +8005,7 @@ btr_copy_zblob_prefix(
default:
inflate_error:
ib::error() << "inflate() of compressed BLOB page "
- << page_id_t(space_id, page_no)
+ << id
<< " returned " << err
<< " (" << d_stream.msg << ")";
@@ -8032,8 +8017,7 @@ inflate_error:
if (!d_stream.avail_in) {
ib::error()
<< "Unexpected end of compressed "
- << "BLOB page "
- << page_id_t(space_id, page_no);
+ << "BLOB page " << id;
} else {
err = inflate(&d_stream, Z_FINISH);
switch (err) {
@@ -8055,7 +8039,7 @@ end_of_blob:
/* On other BLOB pages except the first
the BLOB header always is at the page header: */
- page_no = next_page_no;
+ id.set_page_no(next_page_no);
offset = FIL_PAGE_NEXT;
page_type = FIL_PAGE_TYPE_ZBLOB2;
}
@@ -8074,31 +8058,24 @@ by a lock or a page latch.
field, or a prefix of it
@param[in] len length of buf, in bytes
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
-@param[in] space_id space id of the first BLOB page
-@param[in] page_no page number of the first BLOB page
+@param[in] id page identifier of the first BLOB page
@param[in] offset offset on the first BLOB page
@return number of bytes written to buf */
static
ulint
btr_copy_externally_stored_field_prefix_low(
byte* buf,
- ulint len,
+ uint32_t len,
ulint zip_size,
- ulint space_id,
- ulint page_no,
- ulint offset)
+ page_id_t id,
+ uint32_t offset)
{
- if (len == 0) {
- return(0);
- }
+ if (len == 0)
+ return 0;
- if (zip_size) {
- return(btr_copy_zblob_prefix(buf, len, zip_size,
- space_id, page_no, offset));
- } else {
- return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset));
- }
+ return zip_size
+ ? btr_copy_zblob_prefix(buf, len, zip_size, id, offset)
+ : btr_copy_blob_prefix(buf, len, id, offset);
}
/** Copies the prefix of an externally stored field of a record.
@@ -8120,10 +8097,6 @@ btr_copy_externally_stored_field_prefix(
const byte* data,
ulint local_len)
{
- ulint space_id;
- ulint page_no;
- ulint offset;
-
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
@@ -8146,17 +8119,18 @@ btr_copy_externally_stored_field_prefix(
return(0);
}
- space_id = mach_read_from_4(data + BTR_EXTERN_SPACE_ID);
-
- page_no = mach_read_from_4(data + BTR_EXTERN_PAGE_NO);
-
- offset = mach_read_from_4(data + BTR_EXTERN_OFFSET);
+ uint32_t space_id = mach_read_from_4(data + BTR_EXTERN_SPACE_ID);
+ uint32_t page_no = mach_read_from_4(data + BTR_EXTERN_PAGE_NO);
+ uint32_t offset = mach_read_from_4(data + BTR_EXTERN_OFFSET);
+ len -= local_len;
return(local_len
+ btr_copy_externally_stored_field_prefix_low(buf + local_len,
- len - local_len,
+ uint32_t(len),
zip_size,
- space_id, page_no,
+ page_id_t(
+ space_id,
+ page_no),
offset));
}
@@ -8178,26 +8152,24 @@ btr_copy_externally_stored_field(
ulint local_len,
mem_heap_t* heap)
{
- ulint space_id;
- ulint page_no;
- ulint offset;
- ulint extern_len;
byte* buf;
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
- space_id = mach_read_from_4(data + local_len + BTR_EXTERN_SPACE_ID);
-
- page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO);
-
- offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET);
+ uint32_t space_id = mach_read_from_4(data + local_len
+ + BTR_EXTERN_SPACE_ID);
+ uint32_t page_no = mach_read_from_4(data + local_len
+ + BTR_EXTERN_PAGE_NO);
+ uint32_t offset = mach_read_from_4(data + local_len
+ + BTR_EXTERN_OFFSET);
/* Currently a BLOB cannot be bigger than 4 GB; we
leave the 4 upper bytes in the length field unused */
- extern_len = mach_read_from_4(data + local_len + BTR_EXTERN_LEN + 4);
+ uint32_t extern_len = mach_read_from_4(data + local_len
+ + BTR_EXTERN_LEN + 4);
buf = (byte*) mem_heap_alloc(heap, local_len + extern_len);
@@ -8206,8 +8178,10 @@ btr_copy_externally_stored_field(
+ btr_copy_externally_stored_field_prefix_low(buf + local_len,
extern_len,
zip_size,
- space_id,
- page_no, offset);
+ page_id_t(
+ space_id,
+ page_no),
+ offset);
return(buf);
}
@@ -8253,7 +8227,7 @@ btr_rec_copy_externally_stored_field(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) {
/* The externally stored field was not written yet.
This record should only be seen by
- recv_recovery_rollback_active() or any
+ trx_rollback_recovered() or any
TRX_ISO_READ_UNCOMMITTED transactions. */
return(NULL);
}
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 34099f2b11f..2c4c338ce70 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -50,6 +50,21 @@ possible. From experimentation it seems that reduce the target size by 512 every
time will make sure the page is compressible within a couple of iterations. */
#define BTR_DEFRAGMENT_PAGE_REDUCTION_STEP_SIZE 512
+/** Item in the work queue for btr_degrament_thread. */
+struct btr_defragment_item_t
+{
+ btr_pcur_t* pcur; /* persistent cursor where
+ btr_defragment_n_pages should start */
+ os_event_t event; /* if not null, signal after work
+ is done */
+ bool removed; /* Mark an item as removed */
+ ulonglong last_processed; /* timestamp of last time this index
+ is processed by defragment thread */
+
+ btr_defragment_item_t(btr_pcur_t* pcur, os_event_t event);
+ ~btr_defragment_item_t();
+};
+
/* Work queue for defragmentation. */
typedef std::list<btr_defragment_item_t*> btr_defragment_wq_t;
static btr_defragment_wq_t btr_defragment_wq;
@@ -183,8 +198,6 @@ synchronized defragmentation. */
os_event_t
btr_defragment_add_index(
dict_index_t* index, /*!< index to be added */
- bool async, /*!< whether this is an async
- defragmentation */
dberr_t* err) /*!< out: error code */
{
mtr_t mtr;
@@ -213,10 +226,7 @@ btr_defragment_add_index(
return NULL;
}
btr_pcur_t* pcur = btr_pcur_create_for_mysql();
- os_event_t event = NULL;
- if (!async) {
- event = os_event_create(0);
- }
+ os_event_t event = os_event_create(0);
btr_pcur_open_at_index_side(true, index, BTR_SEARCH_LEAF, pcur,
true, 0, &mtr);
btr_pcur_move_to_next(pcur, &mtr);
@@ -609,7 +619,7 @@ btr_defragment_n_pages(
blocks[0] = block;
for (uint i = 1; i <= n_pages; i++) {
page_t* page = buf_block_get_frame(blocks[i-1]);
- ulint page_no = btr_page_get_next(page);
+ uint32_t page_no = btr_page_get_next(page);
total_data_size += page_get_data_size(page);
total_n_recs += page_get_n_recs(page);
if (page_no == FIL_NULL) {
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index cc8c11c42e1..ad254976973 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -202,11 +202,10 @@ before_first:
cursor->old_n_fields,
&cursor->old_rec_buf,
&cursor->buf_size);
- cursor->block_when_stored = block;
+ cursor->block_when_stored.store(block);
/* Function try to check if block is S/X latch. */
cursor->modify_clock = buf_block_get_modify_clock(block);
- cursor->withdraw_clock = buf_pool.withdraw_clock();
}
/**************************************************************//**
@@ -236,6 +235,26 @@ btr_pcur_copy_stored_position(
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
+/** Structure acts as functor to do the latching of leaf pages.
+It returns true if latching of leaf pages succeeded and false
+otherwise. */
+struct optimistic_latch_leaves
+{
+ btr_pcur_t *const cursor;
+ ulint *latch_mode;
+ mtr_t *const mtr;
+
+ optimistic_latch_leaves(btr_pcur_t *cursor, ulint *latch_mode, mtr_t *mtr)
+ :cursor(cursor), latch_mode(latch_mode), mtr(mtr) {}
+
+ bool operator() (buf_block_t *hint) const
+ {
+ return hint && btr_cur_optimistic_latch_leaves(
+ hint, cursor->modify_clock, latch_mode,
+ btr_pcur_get_btr_cur(cursor), __FILE__, __LINE__, mtr);
+ }
+};
+
/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
@@ -298,7 +317,7 @@ btr_pcur_restore_position_func(
cursor->latch_mode =
BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
- cursor->block_when_stored = btr_pcur_get_block(cursor);
+ cursor->block_when_stored.clear();
return(FALSE);
}
@@ -313,12 +332,9 @@ btr_pcur_restore_position_func(
case BTR_MODIFY_PREV:
/* Try optimistic restoration. */
- if (!buf_pool.is_obsolete(cursor->withdraw_clock)
- && btr_cur_optimistic_latch_leaves(
- cursor->block_when_stored, cursor->modify_clock,
- &latch_mode, btr_pcur_get_btr_cur(cursor),
- file, line, mtr)) {
-
+ if (cursor->block_when_stored.run_with_hint(
+ optimistic_latch_leaves(cursor, &latch_mode,
+ mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->latch_mode = latch_mode;
@@ -416,11 +432,10 @@ btr_pcur_restore_position_func(
since the cursor can now be on a different page!
But we can retain the value of old_rec */
- cursor->block_when_stored = btr_pcur_get_block(cursor);
+ cursor->block_when_stored.store(btr_pcur_get_block(cursor));
cursor->modify_clock = buf_block_get_modify_clock(
- cursor->block_when_stored);
+ cursor->block_when_stored.block());
cursor->old_stored = true;
- cursor->withdraw_clock = buf_pool.withdraw_clock();
mem_heap_free(heap);
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 3b28724c948..68d946aa79d 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -261,9 +261,9 @@ void btr_search_disable()
void btr_search_enable(bool resize)
{
if (!resize) {
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
bool changed = srv_buf_pool_old_size != srv_buf_pool_size;
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
if (changed) {
return;
}
@@ -1913,7 +1913,6 @@ func_exit:
void
btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
{
- btr_search_sys_t::partition* part;
buf_block_t* block;
dict_index_t* index;
const rec_t* rec;
@@ -1982,6 +1981,8 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
n_bytes, index->id);
}
+ /* We must not look up "part" before acquiring ahi_latch. */
+ btr_search_sys_t::partition* part= nullptr;
bool locked = false;
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, *index)) {
@@ -2016,6 +2017,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
part = btr_search_sys.get_part(*index);
}
@@ -2040,6 +2042,7 @@ check_next_rec:
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
part = btr_search_sys.get_part(*index);
}
@@ -2059,6 +2062,7 @@ check_next_rec:
if (!btr_search_enabled || !block->index) {
goto function_exit;
}
+
part = btr_search_sys.get_part(*index);
}
@@ -2136,7 +2140,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
rec_offs_init(offsets_);
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
auto &part = btr_search_sys.parts[hash_table_id];
@@ -2147,7 +2151,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
btr_search_x_unlock_all();
os_thread_yield();
@@ -2159,7 +2163,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
goto func_exit;
}
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
ulint curr_cell_count = part.table.n_cells;
@@ -2255,7 +2259,7 @@ state_ok:
/* We release search latches every once in a while to
give other queries a chance to run. */
if (i != 0) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
btr_search_x_unlock_all();
os_thread_yield();
@@ -2267,7 +2271,7 @@ state_ok:
goto func_exit;
}
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
ulint curr_cell_count = part.table.n_cells;
@@ -2288,7 +2292,7 @@ state_ok:
}
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
func_exit:
btr_search_x_unlock_all();
diff --git a/storage/innobase/buf/buf0block_hint.cc b/storage/innobase/buf/buf0block_hint.cc
new file mode 100644
index 00000000000..6d99d0b61f0
--- /dev/null
+++ b/storage/innobase/buf/buf0block_hint.cc
@@ -0,0 +1,59 @@
+/*****************************************************************************
+
+Copyright (c) 2020, 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, 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, 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, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+*****************************************************************************/
+
+#include "buf0block_hint.h"
+namespace buf {
+
+void Block_hint::buffer_fix_block_if_still_valid()
+{
+ /* To check if m_block belongs to the current buf_pool, we must
+ prevent freeing memory while we check, and until we buffer-fix the
+ block. For this purpose it is enough to latch any of the many
+ latches taken by buf_pool_t::resize().
+
+ Similar to buf_page_optimistic_get(), we must validate
+ m_block->page.id() after acquiring the hash_lock, because the object
+ may have been freed and not actually attached to buf_pool.page_hash
+ at the moment. (The block could have been reused to store a
+ different page, and that slice of buf_pool.page_hash could be protected
+ by another hash_lock that we are not holding.)
+
+ Finally, assuming that we have correct hash bucket latched, we must
+ validate m_block->state() to ensure that the block is not being freed. */
+ if (m_block)
+ {
+ const ulint fold= m_page_id.fold();
+ page_hash_latch *hash_lock= buf_pool.page_hash.lock<false>(fold);
+ if (buf_pool.is_uncompressed(m_block) && m_page_id == m_block->page.id() &&
+ m_block->page.state() == BUF_BLOCK_FILE_PAGE)
+ buf_block_buf_fix_inc(m_block, __FILE__, __LINE__);
+ else
+ clear();
+ hash_lock->read_unlock();
+ }
+}
+} // namespace buf
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index 8280377b42a..f822adc3389 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -192,7 +192,7 @@ static bool buf_buddy_check_free(const buf_buddy_free_t* buf, ulint i)
{
const ulint size = BUF_BUDDY_LOW << i;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(!ut_align_offset(buf, size));
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
@@ -261,7 +261,7 @@ UNIV_INLINE
void
buf_buddy_add_to_free(buf_buddy_free_t* buf, ulint i)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(buf_pool.zip_free[i].start != buf);
buf_buddy_stamp_free(buf, i);
@@ -276,7 +276,7 @@ UNIV_INLINE
void
buf_buddy_remove_from_free(buf_buddy_free_t* buf, ulint i)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(buf_buddy_check_free(buf, i));
UT_LIST_REMOVE(buf_pool.zip_free[i], buf);
@@ -290,7 +290,7 @@ static buf_buddy_free_t* buf_buddy_alloc_zip(ulint i)
{
buf_buddy_free_t* buf;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_a(i < BUF_BUDDY_SIZES);
ut_a(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
@@ -319,7 +319,7 @@ static buf_buddy_free_t* buf_buddy_alloc_zip(ulint i)
if (buf) {
buf_buddy_free_t* buddy =
reinterpret_cast<buf_buddy_free_t*>(
- buf->stamp.bytes
+ reinterpret_cast<byte*>(buf)
+ (BUF_BUDDY_LOW << i));
ut_ad(!buf_pool.contains_zip(buddy));
buf_buddy_add_to_free(buddy, i);
@@ -350,7 +350,7 @@ buf_buddy_block_free(void* buf)
buf_page_t* bpage;
buf_block_t* block;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_a(!ut_align_offset(buf, srv_page_size));
HASH_SEARCH(hash, &buf_pool.zip_hash, fold, buf_page_t*, bpage,
@@ -433,7 +433,7 @@ byte *buf_buddy_alloc_low(ulint i, bool *lru)
{
buf_block_t* block;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
if (i < BUF_BUDDY_SIZES) {
@@ -480,19 +480,17 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
{
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
- ulint space;
- ulint offset;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
MEM_CHECK_ADDRESSABLE(dst, size);
- space = mach_read_from_4((const byte*) src
- + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- offset = mach_read_from_4((const byte*) src
- + FIL_PAGE_OFFSET);
+ uint32_t space = mach_read_from_4(static_cast<const byte*>(src)
+ + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ uint32_t offset = mach_read_from_4(static_cast<const byte*>(src)
+ + FIL_PAGE_OFFSET);
/* Suppress Valgrind or MSAN warnings. */
MEM_MAKE_DEFINED(&space, sizeof space);
@@ -584,7 +582,7 @@ void buf_buddy_free_low(void* buf, ulint i)
{
buf_buddy_free_t* buddy;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(i <= BUF_BUDDY_SIZES);
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
ut_ad(buf_pool.buddy_stat[i].used > 0);
@@ -670,7 +668,7 @@ buf_buddy_realloc(void* buf, ulint size)
buf_block_t* block = NULL;
ulint i = buf_buddy_get_slot(size);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(i <= BUF_BUDDY_SIZES);
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
@@ -711,7 +709,7 @@ buf_buddy_realloc(void* buf, ulint size)
/** Combine all pairs of free buddies. */
void buf_buddy_condense_free()
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(buf_pool.curr_size < buf_pool.old_size);
for (ulint i = 0; i < UT_ARR_SIZE(buf_pool.zip_free); ++i) {
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index ec4b7395ca5..9a180614afd 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -212,12 +212,12 @@ but not written to disk yet. The block with the oldest modification
which has not yet been written to disk is at the end of the chain.
The access to this list is protected by buf_pool.flush_list_mutex.
-The chain of unmodified compressed blocks (buf_pool.zip_clean)
-contains the control blocks (buf_page_t) of those compressed pages
+The control blocks for uncompressed pages are accessible via
+buf_block_t objects that are reachable via buf_pool.chunks[].
+The control blocks (buf_page_t) of those ROW_FORMAT=COMPRESSED pages
that are not in buf_pool.flush_list and for which no uncompressed
-page has been allocated in the buffer pool. The control blocks for
-uncompressed pages are accessible via buf_block_t objects that are
-reachable via buf_pool.chunks[].
+page has been allocated in buf_pool are only accessible via
+buf_pool.LRU.
The chains of free memory blocks (buf_pool.zip_free[]) are used by
the buddy allocator (buf0buddy.cc) to keep track of currently unused
@@ -415,7 +415,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
static bool buf_page_decrypt_after_read(buf_page_t *bpage,
const fil_node_t &node)
{
- ut_ad(node.space->pending_io());
+ ut_ad(node.space->referenced());
ut_ad(node.space->id == bpage->id().space());
const auto flags = node.space->flags;
@@ -475,7 +475,7 @@ decompress_with_slot:
slot->release();
ut_ad(!write_size
|| fil_page_type_validate(node.space, dst_frame));
- ut_ad(node.space->pending_io());
+ ut_ad(node.space->referenced());
return write_size != 0;
}
@@ -516,34 +516,9 @@ decrypt_failed:
goto decompress;
}
- ut_ad(node.space->pending_io());
+ ut_ad(node.space->referenced());
return true;
}
-
-/**
-@return the smallest oldest_modification lsn for any page.
-@retval 0 if all modified persistent pages have been flushed */
-lsn_t buf_pool_t::get_oldest_modification()
-{
- mutex_enter(&flush_list_mutex);
-
- /* FIXME: Keep temporary tablespace pages in a separate flush
- list. We would only need to write out temporary pages if the
- page is about to be evicted from the buffer pool, and the page
- contents is still needed (the page has not been freed). */
- const buf_page_t *bpage;
- for (bpage= UT_LIST_GET_LAST(flush_list);
- bpage && fsp_is_system_temporary(bpage->id().space());
- bpage= UT_LIST_GET_PREV(list, bpage))
- ut_ad(bpage->oldest_modification());
-
- lsn_t oldest_lsn= bpage ? bpage->oldest_modification() : 0;
- mutex_exit(&flush_list_mutex);
-
- /* The result may become stale as soon as we released the mutex.
- On log checkpoint, also log_sys.flush_order_mutex will be needed. */
- return oldest_lsn;
-}
#endif /* !UNIV_INNOCHECKSUM */
/** Checks if the page is in crc32 checksum format.
@@ -719,9 +694,9 @@ static void buf_page_check_lsn(bool check_lsn, const byte* read_buf)
phase it makes no sense to spam the log with error messages. */
if (current_lsn < page_lsn) {
- const ulint space_id = mach_read_from_4(
+ const uint32_t space_id = mach_read_from_4(
read_buf + FIL_PAGE_SPACE_ID);
- const ulint page_no = mach_read_from_4(
+ const uint32_t page_no = mach_read_from_4(
read_buf + FIL_PAGE_OFFSET);
ib::error() << "Page " << page_id_t(space_id, page_no)
@@ -1063,14 +1038,14 @@ buf_madvise_do_dump()
ret+= madvise(recv_sys.buf, recv_sys.len, MADV_DODUMP);
}
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
auto chunk = buf_pool.chunks;
for (ulint n = buf_pool.n_chunks; n--; chunk++) {
ret+= madvise(chunk->mem, chunk->mem_size(), MADV_DODUMP);
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
return ret;
}
#endif
@@ -1504,8 +1479,6 @@ bool buf_pool_t::create()
NUMA_MEMPOLICY_INTERLEAVE_IN_SCOPE;
ut_ad(!resizing);
- ut_ad(!withdrawing);
- ut_ad(!withdraw_clock());
ut_ad(!chunks_old);
chunk_t::map_reg= UT_NEW_NOKEY(chunk_t::map());
@@ -1546,7 +1519,7 @@ bool buf_pool_t::create()
while (++chunk < chunks + n_chunks);
ut_ad(is_initialised());
- mutex_create(LATCH_ID_BUF_POOL, &mutex);
+ mysql_mutex_init(buf_pool_mutex_key, &mutex, MY_MUTEX_INIT_FAST);
UT_LIST_INIT(LRU, &buf_page_t::LRU);
UT_LIST_INIT(withdraw, &buf_page_t::list);
@@ -1554,8 +1527,6 @@ bool buf_pool_t::create()
UT_LIST_INIT(flush_list, &buf_page_t::list);
UT_LIST_INIT(unzip_LRU, &buf_block_t::unzip_LRU);
- ut_d(UT_LIST_INIT(zip_clean, &buf_page_t::list));
-
for (size_t i= 0; i < UT_ARR_SIZE(zip_free); ++i)
UT_LIST_INIT(zip_free[i], &buf_buddy_free_t::list);
ulint s= curr_size;
@@ -1572,17 +1543,18 @@ bool buf_pool_t::create()
zip_hash.create(2 * curr_size);
last_printout_time= time(NULL);
- mutex_create(LATCH_ID_FLUSH_LIST, &flush_list_mutex);
+ mysql_mutex_init(flush_list_mutex_key, &flush_list_mutex,
+ MY_MUTEX_INIT_FAST);
- for (int i= 0; i < 3; i++)
- no_flush[i]= os_event_create(0);
+ mysql_cond_init(0, &done_flush_LRU, nullptr);
+ mysql_cond_init(0, &done_flush_list, nullptr);
+ mysql_cond_init(0, &do_flush_list, nullptr);
try_LRU_scan= true;
ut_d(flush_hp.m_mutex= &flush_list_mutex;);
ut_d(lru_hp.m_mutex= &mutex);
ut_d(lru_scan_itr.m_mutex= &mutex);
- ut_d(single_scan_itr.m_mutex= &mutex);
io_buf.create((srv_n_read_io_threads + srv_n_write_io_threads) *
OS_AIO_N_PENDING_IOS_PER_THREAD);
@@ -1606,14 +1578,8 @@ void buf_pool_t::close()
if (!is_initialised())
return;
- mutex_free(&mutex);
- mutex_free(&flush_list_mutex);
-
- if (flush_rbt)
- {
- rbt_free(flush_rbt);
- flush_rbt= nullptr;
- }
+ mysql_mutex_destroy(&mutex);
+ mysql_mutex_destroy(&flush_list_mutex);
for (buf_page_t *bpage= UT_LIST_GET_LAST(LRU), *prev_bpage= nullptr; bpage;
bpage= prev_bpage)
@@ -1641,8 +1607,9 @@ void buf_pool_t::close()
allocator.deallocate_large_dodump(chunk->mem, &chunk->mem_pfx);
}
- for (int i= 0; i < 3; ++i)
- os_event_destroy(no_flush[i]);
+ mysql_cond_destroy(&done_flush_LRU);
+ mysql_cond_destroy(&done_flush_list);
+ mysql_cond_destroy(&do_flush_list);
ut_free(chunks);
chunks= nullptr;
@@ -1668,8 +1635,7 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
{
buf_block_t* new_block;
- ut_ad(withdrawing);
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
new_block = buf_LRU_get_free_only();
@@ -1740,13 +1706,8 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
MEM_UNDEFINED(block->frame, srv_page_size);
block->page.set_state(BUF_BLOCK_REMOVE_HASH);
-
- /* Relocate flush_list. */
- if (block->page.oldest_modification()) {
- buf_flush_relocate_on_flush_list(
- &block->page, &new_block->page);
- }
-
+ buf_flush_relocate_on_flush_list(&block->page,
+ &new_block->page);
block->page.set_corrupt_id();
/* set other flags of buf_block_t */
@@ -1812,16 +1773,16 @@ inline bool buf_pool_t::withdraw_blocks()
<< withdraw_target << " blocks";
/* Minimize zip_free[i] lists */
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
buf_buddy_condense_free();
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
while (UT_LIST_GET_LEN(withdraw) < withdraw_target) {
/* try to withdraw from free_list */
ulint count1 = 0;
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
block = reinterpret_cast<buf_block_t*>(
UT_LIST_GET_FIRST(free));
while (block != NULL
@@ -1836,7 +1797,7 @@ inline bool buf_pool_t::withdraw_blocks()
UT_LIST_GET_NEXT(
list, &block->page));
- if (buf_pool.will_be_withdrawn(block->page)) {
+ if (will_be_withdrawn(block->page)) {
/* This should be withdrawn */
UT_LIST_REMOVE(free, &block->page);
UT_LIST_ADD_LAST(withdraw, &block->page);
@@ -1846,40 +1807,29 @@ inline bool buf_pool_t::withdraw_blocks()
block = next_block;
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
/* reserve free_list length */
if (UT_LIST_GET_LEN(withdraw) < withdraw_target) {
- ulint scan_depth;
- flush_counters_t n;
-
- /* cap scan_depth with current LRU size. */
- mutex_enter(&mutex);
- scan_depth = UT_LIST_GET_LEN(LRU);
- mutex_exit(&mutex);
-
- scan_depth = ut_min(
- ut_max(withdraw_target
- - UT_LIST_GET_LEN(withdraw),
- static_cast<ulint>(srv_LRU_scan_depth)),
- scan_depth);
+ ulint n_flushed = buf_flush_lists(
+ std::max<ulint>(withdraw_target
+ - UT_LIST_GET_LEN(withdraw),
+ srv_LRU_scan_depth), 0);
+ buf_flush_wait_batch_end_acquiring_mutex(true);
- buf_flush_do_batch(true, scan_depth, 0, &n);
- buf_flush_wait_batch_end(true);
-
- if (n.flushed) {
+ if (n_flushed) {
MONITOR_INC_VALUE_CUMULATIVE(
MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE,
MONITOR_LRU_BATCH_FLUSH_COUNT,
MONITOR_LRU_BATCH_FLUSH_PAGES,
- n.flushed);
+ n_flushed);
}
}
/* relocate blocks/buddies in withdrawn area */
ulint count2 = 0;
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
buf_page_t* bpage;
bpage = UT_LIST_GET_FIRST(LRU);
while (bpage != NULL) {
@@ -1900,7 +1850,7 @@ inline bool buf_pool_t::withdraw_blocks()
}
if (bpage->state() == BUF_BLOCK_FILE_PAGE
- && buf_pool.will_be_withdrawn(*bpage)) {
+ && will_be_withdrawn(*bpage)) {
if (bpage->can_relocate()) {
buf_pool_mutex_exit_forbid();
if (!realloc(
@@ -1919,7 +1869,7 @@ inline bool buf_pool_t::withdraw_blocks()
bpage = next_bpage;
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
buf_resize_status(
"withdrawing blocks. (" ULINTPF "/" ULINTPF ")",
@@ -1956,9 +1906,6 @@ inline bool buf_pool_t::withdraw_blocks()
ib::info() << "withdrawn target: " << UT_LIST_GET_LEN(withdraw)
<< " blocks";
- /* retry is not needed */
- ++withdraw_clock_;
-
return(false);
}
@@ -2039,7 +1986,7 @@ inline void buf_pool_t::page_hash_table::write_unlock_all()
inline void buf_pool_t::write_lock_all_page_hash()
{
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
page_hash.write_lock_all();
for (page_hash_table *old_page_hash= freed_page_hash; old_page_hash;
old_page_hash= static_cast<page_hash_table*>
@@ -2111,16 +2058,15 @@ inline void buf_pool_t::resize()
srv_buf_pool_old_size, srv_buf_pool_size,
srv_buf_pool_chunk_unit);
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
ut_ad(curr_size == old_size);
ut_ad(n_chunks_new == n_chunks);
ut_ad(UT_LIST_GET_LEN(withdraw) == 0);
- ut_ad(flush_rbt == NULL);
n_chunks_new = (new_instance_size << srv_page_size_shift)
/ srv_buf_pool_chunk_unit;
curr_size = n_chunks_new * chunks->size;
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
#ifdef BTR_CUR_HASH_ADAPT
/* disable AHI if needed */
@@ -2153,7 +2099,6 @@ inline void buf_pool_t::resize()
ut_ad(withdraw_target == 0);
withdraw_target = w;
- withdrawing.store(true, std::memory_order_relaxed);
}
buf_resize_status("Withdrawing blocks to be shrunken.");
@@ -2169,7 +2114,6 @@ withdraw_retry:
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
/* abort to resize for shutdown. */
- withdrawing.store(false, std::memory_order_relaxed);
return;
}
@@ -2210,8 +2154,6 @@ withdraw_retry:
goto withdraw_retry;
}
- withdrawing.store(false, std::memory_order_relaxed);
-
buf_resize_status("Latching whole of buffer pool.");
#ifndef DBUG_OFF
@@ -2234,7 +2176,7 @@ withdraw_retry:
/* Indicate critical path */
resizing.store(true, std::memory_order_relaxed);
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
write_lock_all_page_hash();
chunk_t::map_reg = UT_NEW_NOKEY(chunk_t::map());
@@ -2398,7 +2340,7 @@ calc_buf_pool_size:
ib::info() << "hash tables were resized";
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
write_unlock_all_page_hash();
UT_DELETE(chunk_map_old);
@@ -2463,10 +2405,10 @@ static void buf_resize_callback(void *)
{
DBUG_ENTER("buf_resize_callback");
ut_a(srv_shutdown_state == SRV_SHUTDOWN_NONE);
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
const auto size= srv_buf_pool_size;
const bool work= srv_buf_pool_old_size != size;
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
if (work)
buf_pool.resize();
@@ -2504,7 +2446,7 @@ static void buf_relocate(buf_page_t *bpage, buf_page_t *dpage)
{
const ulint fold= bpage->id().fold();
ut_ad(bpage->state() == BUF_BLOCK_ZIP_PAGE);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(buf_pool.hash_lock_get(bpage->id())->is_write_locked());
ut_a(bpage->io_fix() == BUF_IO_NONE);
ut_a(!bpage->buf_fix_count());
@@ -2577,7 +2519,7 @@ retry:
(*hash_lock)->write_unlock();
/* Allocate a watch[] and then try to insert it into the page_hash. */
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
/* The maximum number of purge tasks should never exceed
the UT_ARR_SIZE(watch) - 1, and there is no way for a purge task to hold a
@@ -2601,17 +2543,17 @@ retry:
*hash_lock= page_hash.lock_get(fold);
(*hash_lock)->write_lock();
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
buf_page_t *bpage= page_hash_get_low(id, fold);
if (UNIV_LIKELY_NULL(bpage))
{
(*hash_lock)->write_unlock();
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
w->set_state(BUF_BLOCK_NOT_USED);
*hash_lock= page_hash.lock_get(fold);
(*hash_lock)->write_lock();
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
goto retry;
}
@@ -2624,7 +2566,7 @@ retry:
}
ut_error;
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
return nullptr;
}
@@ -2742,10 +2684,10 @@ err_exit:
{
discard_attempted= true;
hash_lock->read_unlock();
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (buf_page_t *bpage= buf_pool.page_hash_get_low(page_id, fold))
buf_LRU_free_page(bpage, false);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
goto lookup;
}
@@ -2816,7 +2758,7 @@ buf_zip_decompress(
ulint size = page_zip_get_size(&block->page.zip);
/* The tablespace will not be found if this function is called
during IMPORT. */
- fil_space_t* space= fil_space_acquire_for_io(block->page.id().space());
+ fil_space_t* space= fil_space_t::get(block->page.id().space());
const unsigned key_version = mach_read_from_4(
frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
fil_space_crypt_t* crypt_data = space ? space->crypt_data : NULL;
@@ -2853,7 +2795,7 @@ buf_zip_decompress(
if (page_zip_decompress(&block->page.zip,
block->frame, TRUE)) {
if (space) {
- space->release_for_io();
+ space->release();
}
return(TRUE);
}
@@ -2872,7 +2814,7 @@ buf_zip_decompress(
/* Copy to uncompressed storage. */
memcpy(block->frame, frame, block->zip_size());
if (space) {
- space->release_for_io();
+ space->release();
}
return(TRUE);
@@ -2896,7 +2838,7 @@ err_exit:
dict_set_corrupted_by_space(space);
}
- space->release_for_io();
+ space->release();
}
return(FALSE);
@@ -3075,16 +3017,16 @@ buf_page_get_low(
break;
default:
ut_error;
+ case BUF_GET_POSSIBLY_FREED:
+ break;
case BUF_GET_NO_LATCH:
ut_ad(rw_latch == RW_NO_LATCH);
/* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL_OR_WATCH:
- case BUF_GET_POSSIBLY_FREED:
- fil_space_t* s = fil_space_acquire_for_io(page_id.space());
+ fil_space_t* s = fil_space_get(page_id.space());
ut_ad(s);
ut_ad(s->zip_size() == zip_size);
- s->release_for_io();
}
#endif /* UNIV_DEBUG */
@@ -3154,7 +3096,7 @@ lookup:
}
/* The call path is buf_read_page() ->
- buf_read_page_low() (fil_io()) ->
+ buf_read_page_low() (fil_space_t::io()) ->
buf_page_read_complete() ->
buf_decrypt_after_read(). Here fil_space_t* is used
and we decrypt -> buf_page_check_corrupt() where page
@@ -3208,11 +3150,10 @@ lookup:
asserting. */
if (page_id.space() == TRX_SYS_SPACE) {
} else if (page_id.space() == SRV_TMP_SPACE_ID) {
- } else if (fil_space_t* space
- = fil_space_acquire_for_io(
+ } else if (fil_space_t* space= fil_space_t::get(
page_id.space())) {
bool set = dict_set_corrupted_by_space(space);
- space->release_for_io();
+ space->release();
if (set) {
return NULL;
}
@@ -3270,14 +3211,14 @@ got_block:
if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
evict_from_pool:
ut_ad(!fix_block->page.oldest_modification());
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
fix_block->unfix();
if (!buf_LRU_free_page(&fix_block->page, true)) {
ut_ad(0);
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
return(NULL);
}
@@ -3326,7 +3267,7 @@ evict_from_pool:
block = buf_LRU_get_free_block(false);
buf_block_init_low(block);
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
hash_lock = buf_pool.page_hash.lock_get(fold);
hash_lock->write_lock();
@@ -3345,7 +3286,7 @@ evict_from_pool:
hash_lock->write_unlock();
buf_LRU_block_free_non_file_page(block);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
/* Try again */
goto loop;
@@ -3364,12 +3305,7 @@ evict_from_pool:
/* Set after buf_relocate(). */
block->page.set_buf_fix_count(1);
- if (!block->page.oldest_modification()) {
- ut_d(UT_LIST_REMOVE(buf_pool.zip_clean, &block->page));
- } else {
- /* Relocate buf_pool.flush_list. */
- buf_flush_relocate_on_flush_list(bpage, &block->page);
- }
+ buf_flush_relocate_on_flush_list(bpage, &block->page);
/* Buffer-fix, I/O-fix, and X-latch the block
for the duration of the decompression.
@@ -3384,7 +3320,7 @@ evict_from_pool:
MEM_UNDEFINED(bpage, sizeof *bpage);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
hash_lock->write_unlock();
buf_pool.n_pend_unzip++;
@@ -3424,27 +3360,27 @@ evict_from_pool:
ut_ad(fix_block->page.state() == BUF_BLOCK_FILE_PAGE);
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
-
+re_evict:
if (mode != BUF_GET_IF_IN_POOL
&& mode != BUF_GET_IF_IN_POOL_OR_WATCH) {
} else if (!ibuf_debug) {
- } else if (fil_space_t* space =
- fil_space_acquire_for_io(page_id.space())) {
+ } else if (fil_space_t* space = fil_space_t::get(page_id.space())) {
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
fix_block->unfix();
/* Blocks cannot be relocated or enter or exit the
buf_pool while we are holding the buf_pool.mutex. */
+ const bool evicted = buf_LRU_free_page(&fix_block->page, true);
+ space->release();
- if (buf_LRU_free_page(&fix_block->page, true)) {
- space->release_for_io();
+ if (evicted) {
hash_lock = buf_pool.page_hash.lock_get(fold);
hash_lock->write_lock();
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
/* We may set the watch, as it would have
been set if the page were not in the
buffer pool in the first place. */
@@ -3468,20 +3404,16 @@ evict_from_pool:
return(NULL);
}
- bool flushed = fix_block->page.ready_for_flush()
- && buf_flush_page(&fix_block->page,
- IORequest::SINGLE_PAGE, space, true);
- space->release_for_io();
- if (flushed) {
- guess = fix_block;
- goto loop;
- }
-
fix_block->fix();
+ mysql_mutex_unlock(&buf_pool.mutex);
+ buf_flush_lists(ULINT_UNDEFINED, LSN_MAX);
+ buf_flush_wait_batch_end_acquiring_mutex(false);
- /* Failed to evict the page; change it directly */
+ if (!fix_block->page.oldest_modification()) {
+ goto re_evict;
+ }
- mutex_exit(&buf_pool.mutex);
+ /* Failed to evict the page; change it directly */
}
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
@@ -3661,10 +3593,13 @@ buf_page_optimistic_get(
return FALSE;
}
- page_hash_latch *hash_lock = buf_pool.hash_lock_get(block->page.id());
+ const page_id_t id(block->page.id());
+
+ page_hash_latch *hash_lock = buf_pool.hash_lock_get(id);
hash_lock->read_lock();
- if (UNIV_UNLIKELY(block->page.state() != BUF_BLOCK_FILE_PAGE
+ if (UNIV_UNLIKELY(id != block->page.id()
+ || block->page.state() != BUF_BLOCK_FILE_PAGE
|| block->page.io_fix() != BUF_IO_NONE)) {
hash_lock->read_unlock();
return(FALSE);
@@ -3677,8 +3612,7 @@ buf_page_optimistic_get(
buf_page_make_young_if_needed(&block->page);
- ut_ad(!ibuf_inside(mtr)
- || ibuf_page(block->page.id(), block->zip_size(), NULL));
+ ut_ad(!ibuf_inside(mtr) || ibuf_page(id, block->zip_size(), NULL));
mtr_memo_type_t fix_type;
@@ -3691,6 +3625,8 @@ buf_page_optimistic_get(
&block->lock, file, line);
}
+ ut_ad(id == block->page.id());
+
if (!success) {
buf_block_buf_fix_dec(block);
return(FALSE);
@@ -3805,23 +3741,22 @@ FILE_PAGE (the other is buf_page_get_gen).
@param[in] offset offset of the tablespace
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in,out] mtr mini-transaction
+@param[in,out] free_block pre-allocated buffer block
@return pointer to the block, page bufferfixed */
buf_block_t*
buf_page_create(fil_space_t *space, uint32_t offset,
- ulint zip_size, mtr_t *mtr)
+ ulint zip_size, mtr_t *mtr, buf_block_t *free_block)
{
page_id_t page_id(space->id, offset);
ut_ad(mtr->is_active());
ut_ad(page_id.space() != 0 || !zip_size);
space->free_page(offset, false);
-loop:
- buf_block_t *free_block= buf_LRU_get_free_block(false);
free_block->initialise(page_id, zip_size, 1);
const ulint fold= page_id.fold();
-
- mutex_enter(&buf_pool.mutex);
+loop:
+ mysql_mutex_lock(&buf_pool.mutex);
buf_block_t *block= reinterpret_cast<buf_block_t*>
(buf_pool.page_hash_get_low(page_id, fold));
@@ -3832,7 +3767,7 @@ loop:
#ifdef BTR_CUR_HASH_ADAPT
const dict_index_t *drop_hash_entry= nullptr;
#endif
- switch (block->page.state()) {
+ switch (UNIV_EXPECT(block->page.state(), BUF_BLOCK_FILE_PAGE)) {
default:
ut_ad(0);
break;
@@ -3843,16 +3778,15 @@ loop:
while (block->page.io_fix() != BUF_IO_NONE ||
num_fix_count != block->page.buf_fix_count())
{
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
os_thread_yield();
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
}
}
rw_lock_x_lock(&block->lock);
#ifdef BTR_CUR_HASH_ADAPT
drop_hash_entry= block->index;
#endif
- buf_LRU_block_free_non_file_page(free_block);
break;
case BUF_BLOCK_ZIP_PAGE:
page_hash_latch *hash_lock= buf_pool.page_hash.lock_get(fold);
@@ -3860,20 +3794,13 @@ loop:
if (block->page.io_fix() != BUF_IO_NONE)
{
hash_lock->write_unlock();
- buf_LRU_block_free_non_file_page(free_block);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
goto loop;
}
rw_lock_x_lock(&free_block->lock);
buf_relocate(&block->page, &free_block->page);
-
- if (block->page.oldest_modification() > 0)
- buf_flush_relocate_on_flush_list(&block->page, &free_block->page);
-#ifdef UNIV_DEBUG
- else
- UT_LIST_REMOVE(buf_pool.zip_clean, &block->page);
-#endif
+ buf_flush_relocate_on_flush_list(&block->page, &free_block->page);
free_block->page.set_state(BUF_BLOCK_FILE_PAGE);
buf_unzip_LRU_add_block(free_block, FALSE);
@@ -3884,7 +3811,7 @@ loop:
break;
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
#ifdef BTR_CUR_HASH_ADAPT
if (drop_hash_entry)
@@ -3893,6 +3820,13 @@ loop:
mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);
+ if (block->page.ibuf_exist)
+ {
+ if (!recv_recovery_is_on())
+ ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size, true);
+ block->page.ibuf_exist= false;
+ }
+
return block;
}
@@ -3942,7 +3876,7 @@ loop:
else
hash_lock->write_unlock();
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX);
block->page.set_accessed();
@@ -4090,12 +4024,12 @@ static void buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t& space)
/** Release and evict a corrupted page.
@param bpage page that was being read */
-void buf_pool_t::corrupted_evict(buf_page_t *bpage)
+ATTRIBUTE_COLD void buf_pool_t::corrupted_evict(buf_page_t *bpage)
{
const page_id_t id(bpage->id());
page_hash_latch *hash_lock= hash_lock_get(id);
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
hash_lock->write_lock();
ut_ad(bpage->io_fix() == BUF_IO_READ);
@@ -4110,7 +4044,7 @@ void buf_pool_t::corrupted_evict(buf_page_t *bpage)
/* remove from LRU and page_hash */
buf_LRU_free_one_page(bpage, id, hash_lock);
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
ut_d(auto n=) n_pend_reads--;
ut_ad(n > 0);
@@ -4120,6 +4054,7 @@ void buf_pool_t::corrupted_evict(buf_page_t *bpage)
@param[in] bpage Corrupted page
@param[in] node data file
Also remove the bpage from LRU list. */
+ATTRIBUTE_COLD
static void buf_corrupt_page_release(buf_page_t *bpage, const fil_node_t &node)
{
ut_ad(bpage->id().space() == node.space->id);
@@ -4162,7 +4097,7 @@ after decryption normal page checksum does not match.
static dberr_t buf_page_check_corrupt(buf_page_t *bpage,
const fil_node_t &node)
{
- ut_ad(node.space->pending_io());
+ ut_ad(node.space->referenced());
byte* dst_frame = (bpage->zip.data) ? bpage->zip.data :
((buf_block_t*) bpage)->frame;
@@ -4236,7 +4171,7 @@ dberr_t buf_page_read_complete(buf_page_t *bpage, const fil_node_t &node)
{
const page_id_t id(bpage->id());
ut_ad(bpage->in_file());
- ut_ad(id.space() || !buf_dblwr_page_inside(id.page_no()));
+ ut_ad(!buf_dblwr.is_inside(id));
ut_ad(id.space() == node.space->id);
ut_ad(bpage->zip_size() == node.space->zip_size());
@@ -4303,7 +4238,7 @@ dberr_t buf_page_read_complete(buf_page_t *bpage, const fil_node_t &node)
}
err= buf_page_check_corrupt(bpage, node);
- if (err != DB_SUCCESS)
+ if (UNIV_UNLIKELY(err != DB_SUCCESS))
{
database_corrupted:
/* Not a real corruption if it was triggered by error injection */
@@ -4363,7 +4298,7 @@ release_page:
if (bpage->state() == BUF_BLOCK_FILE_PAGE && !recv_no_ibuf_operations &&
(!id.space() || !is_predefined_tablespace(id.space())) &&
fil_page_get_type(frame) == FIL_PAGE_INDEX &&
- page_is_leaf(frame) && ibuf_page_exists(id, bpage->zip_size()))
+ page_is_leaf(frame))
bpage->ibuf_exist= true;
if (UNIV_UNLIKELY(MONITOR_IS_ON(MONITOR_MODULE_BUF_PAGE)))
@@ -4391,12 +4326,12 @@ release_page:
@retval nullptr if all freed */
void buf_pool_t::assert_all_freed()
{
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
const chunk_t *chunk= chunks;
for (auto i= n_chunks; i--; chunk++)
if (const buf_block_t* block= chunk->not_freed())
ib::fatal() << "Page " << block->page.id() << " still fixed or dirty";
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
}
#endif /* UNIV_DEBUG */
@@ -4411,33 +4346,20 @@ void buf_refresh_io_stats()
All pages must be in a replaceable state (not modified or latched). */
void buf_pool_invalidate()
{
- mutex_enter(&buf_pool.mutex);
- ut_ad(!buf_pool.init_flush[IORequest::LRU]);
- ut_ad(!buf_pool.init_flush[IORequest::FLUSH_LIST]);
- ut_ad(!buf_pool.init_flush[IORequest::SINGLE_PAGE]);
- ut_ad(!buf_pool.n_flush[IORequest::SINGLE_PAGE]);
-
- if (buf_pool.n_flush[IORequest::LRU]) {
- mutex_exit(&buf_pool.mutex);
- buf_flush_wait_batch_end(true);
- mutex_enter(&buf_pool.mutex);
- }
+ mysql_mutex_lock(&buf_pool.mutex);
- if (buf_pool.n_flush[IORequest::FLUSH_LIST]) {
- mutex_exit(&buf_pool.mutex);
- buf_flush_wait_batch_end(false);
- mutex_enter(&buf_pool.mutex);
- }
+ buf_flush_wait_batch_end(true);
+ buf_flush_wait_batch_end(false);
/* It is possible that a write batch that has been posted
earlier is still not complete. For buffer pool invalidation to
proceed we must ensure there is NO write activity happening. */
- ut_d(mutex_exit(&buf_pool.mutex));
+ ut_d(mysql_mutex_unlock(&buf_pool.mutex));
ut_d(buf_pool.assert_all_freed());
- ut_d(mutex_enter(&buf_pool.mutex));
+ ut_d(mysql_mutex_lock(&buf_pool.mutex));
- while (buf_LRU_scan_and_free_block(true));
+ while (buf_LRU_scan_and_free_block());
ut_ad(UT_LIST_GET_LEN(buf_pool.LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool.unzip_LRU) == 0);
@@ -4448,7 +4370,7 @@ void buf_pool_invalidate()
memset(&buf_pool.stat, 0x00, sizeof(buf_pool.stat));
buf_refresh_io_stats();
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
#ifdef UNIV_DEBUG
@@ -4460,7 +4382,7 @@ void buf_pool_t::validate()
ulint n_free = 0;
ulint n_zip = 0;
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
chunk_t* chunk = chunks;
@@ -4474,8 +4396,8 @@ void buf_pool_t::validate()
for (j = chunk->size; j--; block++) {
switch (block->page.state()) {
case BUF_BLOCK_ZIP_PAGE:
- /* These should only occur on
- zip_clean, zip_free[], or flush_list. */
+ /* This kind of block descriptors should
+ be allocated by malloc() only. */
ut_error;
break;
@@ -4499,37 +4421,9 @@ void buf_pool_t::validate()
}
}
- /* Check clean compressed-only blocks. */
-
- for (buf_page_t* b = UT_LIST_GET_FIRST(zip_clean); b;
- b = UT_LIST_GET_NEXT(list, b)) {
- ut_ad(b->state() == BUF_BLOCK_ZIP_PAGE);
- ut_ad(!b->oldest_modification());
- switch (b->io_fix()) {
- case BUF_IO_NONE:
- case BUF_IO_PIN:
- /* All clean blocks should be I/O-unfixed. */
- break;
- case BUF_IO_READ:
- /* In buf_LRU_free_page(), we temporarily set
- b->io_fix = BUF_IO_READ for a newly allocated
- control block in order to prevent
- buf_page_get_gen() from decompressing the block. */
- break;
- default:
- ut_error;
- break;
- }
-
- const page_id_t id = b->id();
- ut_ad(page_hash_get_low(id, id.fold()) == b);
- n_lru++;
- n_zip++;
- }
-
/* Check dirty blocks. */
- mutex_enter(&flush_list_mutex);
+ mysql_mutex_lock(&flush_list_mutex);
for (buf_page_t* b = UT_LIST_GET_FIRST(flush_list); b;
b = UT_LIST_GET_NEXT(list, b)) {
ut_ad(b->oldest_modification());
@@ -4555,7 +4449,7 @@ void buf_pool_t::validate()
ut_ad(UT_LIST_GET_LEN(flush_list) == n_flushing);
- mutex_exit(&flush_list_mutex);
+ mysql_mutex_unlock(&flush_list_mutex);
if (curr_size == old_size
&& n_lru + n_free > curr_size + n_zip) {
@@ -4565,7 +4459,7 @@ void buf_pool_t::validate()
<< " zip " << n_zip << ". Aborting...";
}
- ut_ad(UT_LIST_GET_LEN(LRU) == n_lru);
+ ut_ad(UT_LIST_GET_LEN(LRU) >= n_lru);
if (curr_size == old_size
&& UT_LIST_GET_LEN(free) != n_free) {
@@ -4575,7 +4469,7 @@ void buf_pool_t::validate()
<< ", free blocks " << n_free << ". Aborting...";
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
ut_d(buf_LRU_validate());
ut_d(buf_flush_validate());
@@ -4603,8 +4497,8 @@ void buf_pool_t::print()
counts = static_cast<ulint*>(ut_malloc_nokey(sizeof(ulint) * size));
- mutex_enter(&mutex);
- mutex_enter(&flush_list_mutex);
+ mysql_mutex_lock(&mutex);
+ mysql_mutex_lock(&flush_list_mutex);
ib::info()
<< "[buffer pool: size=" << curr_size
@@ -4614,16 +4508,15 @@ void buf_pool_t::print()
<< UT_LIST_GET_LEN(flush_list)
<< ", n pending decompressions=" << n_pend_unzip
<< ", n pending reads=" << n_pend_reads
- << ", n pending flush LRU=" << n_flush[IORequest::LRU]
- << " list=" << n_flush[IORequest::FLUSH_LIST]
- << " single page=" << n_flush[IORequest::SINGLE_PAGE]
+ << ", n pending flush LRU=" << n_flush_LRU
+ << " list=" << n_flush_list
<< ", pages made young=" << stat.n_pages_made_young
<< ", not young=" << stat.n_pages_not_made_young
<< ", pages read=" << stat.n_pages_read
<< ", created=" << stat.n_pages_created
<< ", written=" << stat.n_pages_written << "]";
- mutex_exit(&flush_list_mutex);
+ mysql_mutex_unlock(&flush_list_mutex);
/* Count the number of blocks belonging to each index in the buffer */
@@ -4664,7 +4557,7 @@ void buf_pool_t::print()
}
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
for (i = 0; i < n_found; i++) {
index = dict_index_get_if_in_cache(index_ids[i]);
@@ -4692,66 +4585,18 @@ void buf_pool_t::print()
/** @return the number of latched pages in the buffer pool */
ulint buf_get_latched_pages_number()
{
- buf_page_t* b;
- ulint i;
- ulint fixed_pages_number = 0;
+ ulint fixed_pages_number= 0;
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
- auto chunk = buf_pool.chunks;
-
- for (i = buf_pool.n_chunks; i--; chunk++) {
- buf_block_t* block= chunk->blocks;
-
- for (auto j= chunk->size; j--; block++) {
- if (block->page.state() == BUF_BLOCK_FILE_PAGE
- && (block->page.buf_fix_count()
- || block->page.io_fix() != BUF_IO_NONE)) {
+ for (buf_page_t *b= UT_LIST_GET_FIRST(buf_pool.LRU); b;
+ b= UT_LIST_GET_NEXT(LRU, b))
+ if (b->in_file() && (b->buf_fix_count() || b->io_fix() != BUF_IO_NONE))
+ fixed_pages_number++;
- fixed_pages_number++;
- }
- }
- }
+ mysql_mutex_unlock(&buf_pool.mutex);
- /* Traverse the lists of clean and dirty compressed-only blocks. */
-
- for (b = UT_LIST_GET_FIRST(buf_pool.zip_clean); b;
- b = UT_LIST_GET_NEXT(list, b)) {
- ut_a(b->state() == BUF_BLOCK_ZIP_PAGE);
- ut_a(!b->oldest_modification());
- ut_a(b->io_fix() != BUF_IO_WRITE);
-
- if (b->buf_fix_count() || b->io_fix() != BUF_IO_NONE) {
- fixed_pages_number++;
- }
- }
-
- mutex_enter(&buf_pool.flush_list_mutex);
- for (b = UT_LIST_GET_FIRST(buf_pool.flush_list); b;
- b = UT_LIST_GET_NEXT(list, b)) {
- ut_ad(b->oldest_modification());
-
- switch (b->state()) {
- case BUF_BLOCK_ZIP_PAGE:
- if (b->buf_fix_count() || b->io_fix() != BUF_IO_NONE) {
- fixed_pages_number++;
- }
- continue;
- case BUF_BLOCK_FILE_PAGE:
- /* uncompressed page */
- continue;
- case BUF_BLOCK_NOT_USED:
- case BUF_BLOCK_MEMORY:
- case BUF_BLOCK_REMOVE_HASH:
- break;
- }
- ut_error;
- }
-
- mutex_exit(&buf_pool.flush_list_mutex);
- mutex_exit(&buf_pool.mutex);
-
- return(fixed_pages_number);
+ return fixed_pages_number;
}
#endif /* UNIV_DEBUG */
@@ -4762,8 +4607,8 @@ void buf_stats_get_pool_info(buf_pool_info_t *pool_info)
time_t current_time;
double time_elapsed;
- mutex_enter(&buf_pool.mutex);
- mutex_enter(&buf_pool.flush_list_mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
pool_info->pool_size = buf_pool.curr_size;
@@ -4779,19 +4624,11 @@ void buf_stats_get_pool_info(buf_pool_info_t *pool_info)
pool_info->n_pend_reads = buf_pool.n_pend_reads;
- pool_info->n_pending_flush_lru =
- (buf_pool.n_flush[IORequest::LRU]
- + buf_pool.init_flush[IORequest::LRU]);
-
- pool_info->n_pending_flush_list =
- (buf_pool.n_flush[IORequest::FLUSH_LIST]
- + buf_pool.init_flush[IORequest::FLUSH_LIST]);
+ pool_info->n_pending_flush_lru = buf_pool.n_flush_LRU;
- pool_info->n_pending_flush_single_page =
- (buf_pool.n_flush[IORequest::SINGLE_PAGE]
- + buf_pool.init_flush[IORequest::SINGLE_PAGE]);
+ pool_info->n_pending_flush_list = buf_pool.n_flush_list;
- mutex_exit(&buf_pool.flush_list_mutex);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
@@ -4882,7 +4719,7 @@ void buf_stats_get_pool_info(buf_pool_info_t *pool_info)
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
buf_refresh_io_stats();
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/*********************************************************************//**
@@ -4905,8 +4742,7 @@ buf_print_io_instance(
"Percent of dirty pages(LRU & free pages): %.3f\n"
"Max dirty pages percent: %.3f\n"
"Pending reads " ULINTPF "\n"
- "Pending writes: LRU " ULINTPF ", flush list " ULINTPF
- ", single page " ULINTPF "\n",
+ "Pending writes: LRU " ULINTPF ", flush list " ULINTPF "\n",
pool_info->pool_size,
pool_info->free_list_len,
pool_info->lru_len,
@@ -4919,8 +4755,7 @@ buf_print_io_instance(
srv_max_buf_pool_modified_pct,
pool_info->n_pend_reads,
pool_info->n_pending_flush_lru,
- pool_info->n_pending_flush_list,
- pool_info->n_pending_flush_single_page);
+ pool_info->n_pending_flush_list);
fprintf(file,
"Pages made young " ULINTPF ", not young " ULINTPF "\n"
@@ -5021,17 +4856,4 @@ std::ostream& operator<<(std::ostream &out, const page_id_t page_id)
<< ", page number=" << page_id.page_no() << "]";
return out;
}
-
-/**
-Calculate the length of trim (punch_hole) operation.
-@param[in] bpage Page control block
-@param[in] write_length Write length
-@return length of the trim or zero. */
-ulint
-buf_page_get_trim_length(
- const buf_page_t* bpage,
- ulint write_length)
-{
- return bpage->physical_size() - write_length;
-}
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 4b2822bf865..f17cf6cc128 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -29,6 +29,7 @@ Created 2011/12/19
#include "buf0checksum.h"
#include "srv0start.h"
#include "srv0srv.h"
+#include "sync0sync.h"
#include "page0zip.h"
#include "trx0sys.h"
#include "fil0crypt.h"
@@ -37,41 +38,7 @@ Created 2011/12/19
using st_::span;
/** The doublewrite buffer */
-buf_dblwr_t* buf_dblwr = NULL;
-
-/** Set to TRUE when the doublewrite buffer is being created */
-ibool buf_dblwr_being_created = FALSE;
-
-#define TRX_SYS_DOUBLEWRITE_BLOCKS 2
-
-/****************************************************************//**
-Determines if a page number is located inside the doublewrite buffer.
-@return TRUE if the location is inside the two blocks of the
-doublewrite buffer */
-ibool
-buf_dblwr_page_inside(
-/*==================*/
- ulint page_no) /*!< in: page number */
-{
- if (buf_dblwr == NULL) {
-
- return(FALSE);
- }
-
- if (page_no >= buf_dblwr->block1
- && page_no < buf_dblwr->block1
- + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
- return(TRUE);
- }
-
- if (page_no >= buf_dblwr->block2
- && page_no < buf_dblwr->block2
- + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
- return(TRUE);
- }
-
- return(FALSE);
-}
+buf_dblwr_t buf_dblwr;
/** @return the TRX_SYS page */
inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr)
@@ -82,619 +49,450 @@ inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr)
return block;
}
-/****************************************************************//**
-Creates or initialializes the doublewrite buffer at a database start. */
-static void buf_dblwr_init(const byte *doublewrite)
+/** Initialize the doublewrite buffer data structure.
+@param header doublewrite page header in the TRX_SYS page */
+inline void buf_dblwr_t::init(const byte *header)
{
- ulint buf_size;
+ ut_ad(!active_slot->first_free);
+ ut_ad(!active_slot->reserved);
+ ut_ad(!batch_running);
- buf_dblwr = static_cast<buf_dblwr_t*>(
- ut_zalloc_nokey(sizeof(buf_dblwr_t)));
+ mysql_mutex_init(buf_dblwr_mutex_key, &mutex, nullptr);
+ mysql_cond_init(0, &cond, nullptr);
+ block1= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK1));
+ block2= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK2));
- /* There are two blocks of same size in the doublewrite
- buffer. */
- buf_size = TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
+ const uint32_t buf_size= 2 * block_size();
+ for (int i= 0; i < 2; i++)
+ {
+ slots[i].write_buf= static_cast<byte*>
+ (aligned_malloc(buf_size << srv_page_size_shift, srv_page_size));
+ slots[i].buf_block_arr= static_cast<element*>
+ (ut_zalloc_nokey(buf_size * sizeof(element)));
+ }
+ active_slot= &slots[0];
+}
- /* There must be atleast one buffer for single page writes
- and one buffer for batch writes. */
- ut_a(srv_doublewrite_batch_size > 0
- && srv_doublewrite_batch_size < buf_size);
+/** Create or restore the doublewrite buffer in the TRX_SYS page.
+@return whether the operation succeeded */
+bool buf_dblwr_t::create()
+{
+ if (is_initialised())
+ return true;
- mutex_create(LATCH_ID_BUF_DBLWR, &buf_dblwr->mutex);
+ mtr_t mtr;
+ const ulint size= block_size();
- buf_dblwr->b_event = os_event_create("dblwr_batch_event");
- buf_dblwr->s_event = os_event_create("dblwr_single_event");
- buf_dblwr->first_free = 0;
- buf_dblwr->s_reserved = 0;
- buf_dblwr->b_reserved = 0;
+start_again:
+ mtr.start();
- buf_dblwr->block1 = mach_read_from_4(
- doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1);
- buf_dblwr->block2 = mach_read_from_4(
- doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2);
+ buf_block_t *trx_sys_block= buf_dblwr_trx_sys_get(&mtr);
- buf_dblwr->write_buf = static_cast<byte*>(
- aligned_malloc(buf_size << srv_page_size_shift,
- srv_page_size));
+ if (mach_read_from_4(TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC +
+ trx_sys_block->frame) == TRX_SYS_DOUBLEWRITE_MAGIC_N)
+ {
+ /* The doublewrite buffer has already been created: just read in
+ some numbers */
+ init(TRX_SYS_DOUBLEWRITE + trx_sys_block->frame);
+ mtr.commit();
+ return true;
+ }
- buf_dblwr->buf_block_arr = static_cast<buf_dblwr_t::element*>(
- ut_zalloc_nokey(buf_size * sizeof(buf_dblwr_t::element)));
-}
+ if (UT_LIST_GET_FIRST(fil_system.sys_space->chain)->size < 3 * size)
+ {
+too_small:
+ ib::error() << "Cannot create doublewrite buffer: "
+ "the first file in innodb_data_file_path must be at least "
+ << (3 * (size >> (20U - srv_page_size_shift))) << "M.";
+ mtr.commit();
+ return false;
+ }
+ else
+ {
+ buf_block_t *b= fseg_create(fil_system.sys_space,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG,
+ &mtr, false, trx_sys_block);
+ if (!b)
+ goto too_small;
+ ib::info() << "Doublewrite buffer not found: creating new";
+
+ /* FIXME: After this point, the doublewrite buffer creation
+ is not atomic. The doublewrite buffer should not exist in
+ the InnoDB system tablespace file in the first place.
+ It could be located in separate optional file(s) in a
+ user-specified location. */
+
+ /* fseg_create acquires a second latch on the page,
+ therefore we must declare it: */
+ buf_block_dbg_add_level(b, SYNC_NO_ORDER_CHECK);
+ }
-/** Create the doublewrite buffer if the doublewrite buffer header
-is not present in the TRX_SYS page.
-@return whether the operation succeeded
-@retval true if the doublewrite buffer exists or was created
-@retval false if the creation failed (too small first data file) */
-bool
-buf_dblwr_create()
-{
- buf_block_t* block2;
- buf_block_t* new_block;
- byte* fseg_header;
- ulint page_no;
- ulint prev_page_no;
- ulint i;
- mtr_t mtr;
-
- if (buf_dblwr) {
- /* Already inited */
- return(true);
- }
+ byte *fseg_header= TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG +
+ trx_sys_block->frame;
+ for (uint32_t prev_page_no= 0, i= 0, extent_size= FSP_EXTENT_SIZE;
+ i < 2 * size + extent_size / 2; i++)
+ {
+ buf_block_t *new_block= fseg_alloc_free_page(fseg_header, prev_page_no + 1,
+ FSP_UP, &mtr);
+ if (!new_block)
+ {
+ ib::error() << "Cannot create doublewrite buffer: "
+ " you must increase your tablespace size."
+ " Cannot continue operation.";
+ /* This may essentially corrupt the doublewrite
+ buffer. However, usually the doublewrite buffer
+ is created at database initialization, and it
+ should not matter (just remove all newly created
+ InnoDB files and restart). */
+ mtr.commit();
+ return false;
+ }
-start_again:
- mtr.start();
- buf_dblwr_being_created = TRUE;
-
- buf_block_t *trx_sys_block = buf_dblwr_trx_sys_get(&mtr);
-
- if (mach_read_from_4(TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
- + trx_sys_block->frame)
- == TRX_SYS_DOUBLEWRITE_MAGIC_N) {
- /* The doublewrite buffer has already been created:
- just read in some numbers */
-
- buf_dblwr_init(TRX_SYS_DOUBLEWRITE + trx_sys_block->frame);
-
- mtr.commit();
- buf_dblwr_being_created = FALSE;
- return(true);
- } else {
- if (UT_LIST_GET_FIRST(fil_system.sys_space->chain)->size
- < 3 * FSP_EXTENT_SIZE) {
- goto too_small;
- }
- }
-
- block2 = fseg_create(fil_system.sys_space,
- TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG,
- &mtr, false, trx_sys_block);
-
- if (block2 == NULL) {
-too_small:
- ib::error()
- << "Cannot create doublewrite buffer: "
- "the first file in innodb_data_file_path"
- " must be at least "
- << (3 * (FSP_EXTENT_SIZE
- >> (20U - srv_page_size_shift)))
- << "M.";
- mtr.commit();
- return(false);
- }
-
- ib::info() << "Doublewrite buffer not found: creating new";
-
- /* FIXME: After this point, the doublewrite buffer creation
- is not atomic. The doublewrite buffer should not exist in
- the InnoDB system tablespace file in the first place.
- It could be located in separate optional file(s) in a
- user-specified location. */
-
- /* fseg_create acquires a second latch on the page,
- therefore we must declare it: */
-
- buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
-
- fseg_header = TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG
- + trx_sys_block->frame;
- prev_page_no = 0;
-
- for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
- + FSP_EXTENT_SIZE / 2; i++) {
- new_block = fseg_alloc_free_page(
- fseg_header, prev_page_no + 1, FSP_UP, &mtr);
- if (new_block == NULL) {
- ib::error() << "Cannot create doublewrite buffer: "
- " you must increase your tablespace size."
- " Cannot continue operation.";
- /* This may essentially corrupt the doublewrite
- buffer. However, usually the doublewrite buffer
- is created at database initialization, and it
- should not matter (just remove all newly created
- InnoDB files and restart). */
- mtr.commit();
- return(false);
- }
-
- /* We read the allocated pages to the buffer pool;
- when they are written to disk in a flush, the space
- id and page number fields are also written to the
- pages. When we at database startup read pages
- from the doublewrite buffer, we know that if the
- space id and page number in them are the same as
- the page position in the tablespace, then the page
- has not been written to in doublewrite. */
-
- ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1);
- page_no = new_block->page.id().page_no();
- /* We only do this in the debug build, to ensure that
- the check in buf_flush_init_for_writing() will see a valid
- page type. The flushes of new_block are actually
- unnecessary here. */
- ut_d(mtr.write<2>(*new_block,
- FIL_PAGE_TYPE + new_block->frame,
- FIL_PAGE_TYPE_SYS));
-
- if (i == FSP_EXTENT_SIZE / 2) {
- ut_a(page_no == FSP_EXTENT_SIZE);
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_BLOCK1
- + trx_sys_block->frame,
- page_no);
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_REPEAT
- + TRX_SYS_DOUBLEWRITE_BLOCK1
- + trx_sys_block->frame,
- page_no);
-
- } else if (i == FSP_EXTENT_SIZE / 2
- + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
- ut_a(page_no == 2 * FSP_EXTENT_SIZE);
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_BLOCK2
- + trx_sys_block->frame,
- page_no);
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_REPEAT
- + TRX_SYS_DOUBLEWRITE_BLOCK2
- + trx_sys_block->frame,
- page_no);
- } else if (i > FSP_EXTENT_SIZE / 2) {
- ut_a(page_no == prev_page_no + 1);
- }
-
- if (((i + 1) & 15) == 0) {
- /* rw_locks can only be recursively x-locked
- 2048 times. (on 32 bit platforms,
- (lint) 0 - (X_LOCK_DECR * 2049)
- is no longer a negative number, and thus
- lock_word becomes like a shared lock).
- For 4k page size this loop will
- lock the fseg header too many times. Since
- this code is not done while any other threads
- are active, restart the MTR occasionally. */
- mtr.commit();
- mtr.start();
- trx_sys_block = buf_dblwr_trx_sys_get(&mtr);
- fseg_header = TRX_SYS_DOUBLEWRITE
- + TRX_SYS_DOUBLEWRITE_FSEG
- + trx_sys_block->frame;
- }
-
- prev_page_no = page_no;
- }
-
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
- + trx_sys_block->frame,
- TRX_SYS_DOUBLEWRITE_MAGIC_N);
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
- + TRX_SYS_DOUBLEWRITE_REPEAT
- + trx_sys_block->frame,
- TRX_SYS_DOUBLEWRITE_MAGIC_N);
-
- mtr.write<4>(*trx_sys_block,
- TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED
- + trx_sys_block->frame,
- TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
- mtr.commit();
-
- /* Flush the modified pages to disk and make a checkpoint */
- log_make_checkpoint();
- buf_dblwr_being_created = FALSE;
-
- /* Remove doublewrite pages from LRU */
- buf_pool_invalidate();
-
- ib::info() << "Doublewrite buffer created";
-
- goto start_again;
+ /* We read the allocated pages to the buffer pool; when they are
+ written to disk in a flush, the space id and page number fields
+ are also written to the pages. When we at database startup read
+ pages from the doublewrite buffer, we know that if the space id
+ and page number in them are the same as the page position in the
+ tablespace, then the page has not been written to in
+ doublewrite. */
+
+ ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1);
+ const page_id_t id= new_block->page.id();
+ /* We only do this in the debug build, to ensure that the check in
+ buf_flush_init_for_writing() will see a valid page type. The
+ flushes of new_block are actually unnecessary here. */
+ ut_d(mtr.write<2>(*new_block, FIL_PAGE_TYPE + new_block->frame,
+ FIL_PAGE_TYPE_SYS));
+
+ if (i == size / 2)
+ {
+ ut_a(id.page_no() == size);
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_BLOCK1 +
+ trx_sys_block->frame, id.page_no());
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_REPEAT +
+ TRX_SYS_DOUBLEWRITE_BLOCK1 + trx_sys_block->frame,
+ id.page_no());
+ }
+ else if (i == size / 2 + size)
+ {
+ ut_a(id.page_no() == 2 * size);
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_BLOCK2 +
+ trx_sys_block->frame, id.page_no());
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_REPEAT +
+ TRX_SYS_DOUBLEWRITE_BLOCK2 + trx_sys_block->frame,
+ id.page_no());
+ }
+ else if (i > size / 2)
+ ut_a(id.page_no() == prev_page_no + 1);
+
+ if (((i + 1) & 15) == 0) {
+ /* rw_locks can only be recursively x-locked 2048 times. (on 32
+ bit platforms, (lint) 0 - (X_LOCK_DECR * 2049) is no longer a
+ negative number, and thus lock_word becomes like a shared lock).
+ For 4k page size this loop will lock the fseg header too many
+ times. Since this code is not done while any other threads are
+ active, restart the MTR occasionally. */
+ mtr.commit();
+ mtr.start();
+ trx_sys_block= buf_dblwr_trx_sys_get(&mtr);
+ fseg_header= TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG +
+ trx_sys_block->frame;
+ }
+
+ prev_page_no= id.page_no();
+ }
+
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC +
+ trx_sys_block->frame, TRX_SYS_DOUBLEWRITE_MAGIC_N);
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC +
+ TRX_SYS_DOUBLEWRITE_REPEAT + trx_sys_block->frame,
+ TRX_SYS_DOUBLEWRITE_MAGIC_N);
+
+ mtr.write<4>(*trx_sys_block,
+ TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
+ trx_sys_block->frame, TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
+ mtr.commit();
+
+ /* Flush the modified pages to disk and make a checkpoint */
+ log_make_checkpoint();
+
+ /* Remove doublewrite pages from LRU */
+ buf_pool_invalidate();
+
+ ib::info() << "Doublewrite buffer created";
+ goto start_again;
}
-/**
-At database startup initializes the doublewrite buffer memory structure if
-we already have a doublewrite buffer created in the data files. If we are
-upgrading to an InnoDB version which supports multiple tablespaces, then this
-function performs the necessary update operations. If we are in a crash
-recovery, this function loads the pages from double write buffer into memory.
-@param[in] file File handle
-@param[in] path Path name of file
+/** Initialize the doublewrite buffer memory structure on recovery.
+If we are upgrading from a version before MySQL 4.1, then this
+function performs the necessary update operations to support
+innodb_file_per_table. If we are in a crash recovery, this function
+loads the pages from double write buffer into memory.
+@param file File handle
+@param path Path name of file
@return DB_SUCCESS or error code */
-dberr_t
-buf_dblwr_init_or_load_pages(
- pfs_os_file_t file,
- const char* path)
+dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path)
{
- byte* buf;
- byte* page;
- ulint block1;
- ulint block2;
- ulint space_id;
- byte* read_buf;
- byte* doublewrite;
- ibool reset_space_ids = FALSE;
- recv_dblwr_t& recv_dblwr = recv_sys.dblwr;
-
- /* We do the file i/o past the buffer pool */
- read_buf = static_cast<byte*>(
- aligned_malloc(2 * srv_page_size, srv_page_size));
-
- /* Read the trx sys header to check if we are using the doublewrite
- buffer */
- dberr_t err;
-
- IORequest read_request(IORequest::READ);
-
- err = os_file_read(
- read_request,
- file, read_buf, TRX_SYS_PAGE_NO << srv_page_size_shift,
- srv_page_size);
-
- if (err != DB_SUCCESS) {
-
- ib::error()
- << "Failed to read the system tablespace header page";
+ ut_ad(this == &buf_dblwr);
+ const uint32_t size= block_size();
+
+ /* We do the file i/o past the buffer pool */
+ byte *read_buf= static_cast<byte*>(aligned_malloc(srv_page_size,
+ srv_page_size));
+ /* Read the TRX_SYS header to check if we are using the doublewrite buffer */
+ dberr_t err= os_file_read(IORequestRead, file, read_buf,
+ TRX_SYS_PAGE_NO << srv_page_size_shift,
+ srv_page_size);
+
+ if (err != DB_SUCCESS)
+ {
+ ib::error() << "Failed to read the system tablespace header page";
func_exit:
- aligned_free(read_buf);
- return(err);
- }
-
- doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
-
- /* TRX_SYS_PAGE_NO is not encrypted see fil_crypt_rotate_page() */
-
- if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
- == TRX_SYS_DOUBLEWRITE_MAGIC_N) {
- /* The doublewrite buffer has been created */
-
- buf_dblwr_init(doublewrite);
-
- block1 = buf_dblwr->block1;
- block2 = buf_dblwr->block2;
-
- buf = buf_dblwr->write_buf;
- } else {
- err = DB_SUCCESS;
- goto func_exit;
- }
-
- if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED)
- != TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N) {
-
- /* We are upgrading from a version < 4.1.x to a version where
- multiple tablespaces are supported. We must reset the space id
- field in the pages in the doublewrite buffer because starting
- from this version the space id is stored to
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
-
- reset_space_ids = TRUE;
-
- ib::info() << "Resetting space id's in the doublewrite buffer";
- }
-
- /* Read the pages from the doublewrite buffer to memory */
- err = os_file_read(
- read_request,
- file, buf, block1 << srv_page_size_shift,
- TRX_SYS_DOUBLEWRITE_BLOCK_SIZE << srv_page_size_shift);
-
- if (err != DB_SUCCESS) {
-
- ib::error()
- << "Failed to read the first double write buffer "
- "extent";
- goto func_exit;
- }
-
- err = os_file_read(
- read_request,
- file,
- buf + (TRX_SYS_DOUBLEWRITE_BLOCK_SIZE << srv_page_size_shift),
- block2 << srv_page_size_shift,
- TRX_SYS_DOUBLEWRITE_BLOCK_SIZE << srv_page_size_shift);
-
- if (err != DB_SUCCESS) {
-
- ib::error()
- << "Failed to read the second double write buffer "
- "extent";
- goto func_exit;
- }
-
- /* Check if any of these pages is half-written in data files, in the
- intended position */
-
- page = buf;
-
- for (ulint i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) {
-
- if (reset_space_ids) {
- ulint source_page_no;
-
- space_id = 0;
- mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
- space_id);
- /* We do not need to calculate new checksums for the
- pages because the field .._SPACE_ID does not affect
- them. Write the page back to where we read it from. */
-
- if (i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
- source_page_no = block1 + i;
- } else {
- source_page_no = block2
- + i - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
- }
-
- err = os_file_write(
- IORequestWrite, path, file, page,
- source_page_no << srv_page_size_shift,
- srv_page_size);
- if (err != DB_SUCCESS) {
-
- ib::error()
- << "Failed to write to the double write"
- " buffer";
- goto func_exit;
- }
- } else if (mach_read_from_8(page + FIL_PAGE_LSN)) {
- /* Each valid page header must contain
- a nonzero FIL_PAGE_LSN field. */
- recv_dblwr.add(page);
- }
-
- page += srv_page_size;
- }
-
- if (reset_space_ids) {
- os_file_flush(file);
- }
-
- err = DB_SUCCESS;
- goto func_exit;
+ aligned_free(read_buf);
+ return err;
+ }
+
+ /* TRX_SYS_PAGE_NO is not encrypted see fil_crypt_rotate_page() */
+ if (mach_read_from_4(TRX_SYS_DOUBLEWRITE_MAGIC + TRX_SYS_DOUBLEWRITE +
+ read_buf) != TRX_SYS_DOUBLEWRITE_MAGIC_N)
+ {
+ /* There is no doublewrite buffer initialized in the TRX_SYS page.
+ This should normally not be possible; the doublewrite buffer should
+ be initialized when creating the database. */
+ err= DB_SUCCESS;
+ goto func_exit;
+ }
+
+ init(TRX_SYS_DOUBLEWRITE + read_buf);
+
+ const bool upgrade_to_innodb_file_per_table=
+ mach_read_from_4(TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
+ TRX_SYS_DOUBLEWRITE + read_buf) !=
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N;
+
+ auto write_buf= active_slot->write_buf;
+ /* Read the pages from the doublewrite buffer to memory */
+ err= os_file_read(IORequestRead, file, write_buf,
+ block1.page_no() << srv_page_size_shift,
+ size << srv_page_size_shift);
+
+ if (err != DB_SUCCESS)
+ {
+ ib::error() << "Failed to read the first double write buffer extent";
+ goto func_exit;
+ }
+
+ err= os_file_read(IORequestRead, file,
+ write_buf + (size << srv_page_size_shift),
+ block2.page_no() << srv_page_size_shift,
+ size << srv_page_size_shift);
+ if (err != DB_SUCCESS)
+ {
+ ib::error() << "Failed to read the second double write buffer extent";
+ goto func_exit;
+ }
+
+ byte *page= write_buf;
+
+ if (UNIV_UNLIKELY(upgrade_to_innodb_file_per_table))
+ {
+ ib::info() << "Resetting space id's in the doublewrite buffer";
+
+ for (ulint i= 0; i < size * 2; i++, page += srv_page_size)
+ {
+ memset(page + FIL_PAGE_SPACE_ID, 0, 4);
+ /* For innodb_checksum_algorithm=innodb, we do not need to
+ calculate new checksums for the pages because the field
+ .._SPACE_ID does not affect them. Write the page back to where
+ we read it from. */
+ const ulint source_page_no= i < size
+ ? block1.page_no() + i
+ : block2.page_no() + i - size;
+ err= os_file_write(IORequestWrite, path, file, page,
+ source_page_no << srv_page_size_shift, srv_page_size);
+ if (err != DB_SUCCESS)
+ {
+ ib::error() << "Failed to upgrade the double write buffer";
+ goto func_exit;
+ }
+ }
+ os_file_flush(file);
+ }
+ else
+ for (ulint i= 0; i < size * 2; i++, page += srv_page_size)
+ if (mach_read_from_8(my_assume_aligned<8>(page + FIL_PAGE_LSN)))
+ /* Each valid page header must contain a nonzero FIL_PAGE_LSN field. */
+ recv_sys.dblwr.add(page);
+
+ err= DB_SUCCESS;
+ goto func_exit;
}
/** Process and remove the double write buffer pages for all tablespaces. */
-void
-buf_dblwr_process()
+void buf_dblwr_t::recover()
{
- ut_ad(recv_sys.parse_start_lsn);
-
- ulint page_no_dblwr = 0;
- byte* read_buf;
- recv_dblwr_t& recv_dblwr = recv_sys.dblwr;
-
- if (!buf_dblwr) {
- return;
- }
-
- read_buf = static_cast<byte*>(
- aligned_malloc(3 * srv_page_size, srv_page_size));
- byte* const buf = read_buf + srv_page_size;
-
- for (recv_dblwr_t::list::iterator i = recv_dblwr.pages.begin();
- i != recv_dblwr.pages.end();
- ++i, ++page_no_dblwr) {
- byte* page = *i;
- const ulint page_no = page_get_page_no(page);
-
- if (!page_no) {
- /* page 0 should have been recovered
- already via Datafile::restore_from_doublewrite() */
- continue;
- }
-
- const ulint space_id = page_get_space_id(page);
- const lsn_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
-
- if (recv_sys.parse_start_lsn > lsn) {
- /* Pages written before the checkpoint are
- not useful for recovery. */
- continue;
- }
-
- const page_id_t page_id(space_id, page_no);
-
- if (recv_sys.scanned_lsn < lsn) {
- ib::warn() << "Ignoring a doublewrite copy of page "
- << page_id
- << " with future log sequence number "
- << lsn;
- continue;
- }
-
- fil_space_t* space = fil_space_acquire_for_io(space_id);
-
- if (!space) {
- /* Maybe we have dropped the tablespace
- and this page once belonged to it: do nothing */
- continue;
- }
-
- fil_space_open_if_needed(space);
-
- if (UNIV_UNLIKELY(page_no >= space->size)) {
-
- /* Do not report the warning for undo
- tablespaces, because they can be truncated in place. */
- if (!srv_is_undo_tablespace(space_id)) {
- ib::warn() << "A copy of page " << page_no
- << " in the doublewrite buffer slot "
- << page_no_dblwr
- << " is beyond the end of tablespace "
- << space->name
- << " (" << space->size << " pages)";
- }
+ ut_ad(recv_sys.parse_start_lsn);
+ if (!is_initialised())
+ return;
+
+ uint32_t page_no_dblwr= 0;
+ byte *read_buf= static_cast<byte*>(aligned_malloc(3 * srv_page_size,
+ srv_page_size));
+ byte *const buf= read_buf + srv_page_size;
+
+ for (recv_dblwr_t::list::iterator i= recv_sys.dblwr.pages.begin();
+ i != recv_sys.dblwr.pages.end(); ++i, ++page_no_dblwr)
+ {
+ byte *page= *i;
+ const uint32_t page_no= page_get_page_no(page);
+ if (!page_no) /* recovered via Datafile::restore_from_doublewrite() */
+ continue;
+
+ const lsn_t lsn= mach_read_from_8(page + FIL_PAGE_LSN);
+ if (recv_sys.parse_start_lsn > lsn)
+ /* Pages written before the checkpoint are not useful for recovery. */
+ continue;
+ const ulint space_id= page_get_space_id(page);
+ const page_id_t page_id(space_id, page_no);
+
+ if (recv_sys.scanned_lsn < lsn)
+ {
+ ib::warn() << "Ignoring a doublewrite copy of page " << page_id
+ << " with future log sequence number " << lsn;
+ continue;
+ }
+
+ fil_space_t *space= fil_space_t::get(space_id);
+
+ if (!space)
+ /* The tablespace that this page once belonged to does not exist */
+ continue;
+
+ if (UNIV_UNLIKELY(page_no >= space->get_size()))
+ {
+ /* Do not report the warning for undo tablespaces, because they
+ can be truncated in place. */
+ if (!srv_is_undo_tablespace(space_id))
+ ib::warn() << "A copy of page " << page_no
+ << " in the doublewrite buffer slot " << page_no_dblwr
+ << " is beyond the end of tablespace " << space->name
+ << " (" << space->size << " pages)";
next_page:
- space->release_for_io();
- continue;
- }
-
- const ulint physical_size = space->physical_size();
- const ulint zip_size = space->zip_size();
- ut_ad(!buf_is_zeroes(span<const byte>(page, physical_size)));
-
- /* We want to ensure that for partial reads the
- unread portion of the page is NUL. */
- memset(read_buf, 0x0, physical_size);
-
- IORequest request;
-
- request.dblwr_recover();
-
- /* Read in the actual page from the file */
- fil_io_t fio = fil_io(
- request, true,
- page_id, zip_size,
- 0, physical_size, read_buf, NULL);
-
- if (UNIV_UNLIKELY(fio.err != DB_SUCCESS)) {
- ib::warn()
- << "Double write buffer recovery: "
- << page_id << " read failed with "
- << "error: " << fio.err;
- }
-
- if (fio.node) {
- fio.node->space->release_for_io();
- }
-
- if (buf_is_zeroes(span<const byte>(read_buf, physical_size))) {
- /* We will check if the copy in the
- doublewrite buffer is valid. If not, we will
- ignore this page (there should be redo log
- records to initialize it). */
- } else if (recv_dblwr.validate_page(
- page_id, read_buf, space, buf)) {
- goto next_page;
- } else {
- /* We intentionally skip this message for
- all-zero pages. */
- ib::info()
- << "Trying to recover page " << page_id
- << " from the doublewrite buffer.";
- }
-
- page = recv_dblwr.find_page(page_id, space, buf);
-
- if (!page) {
- goto next_page;
- }
-
- /* Write the good page from the doublewrite buffer to
- the intended position. */
- fio = fil_io(IORequestWrite, true, page_id, zip_size,
- 0, physical_size, page, nullptr);
-
- if (fio.node) {
- ut_ad(fio.err == DB_SUCCESS);
- ib::info() << "Recovered page " << page_id
- << " to '" << fio.node->name
- << "' from the doublewrite buffer.";
- fio.node->space->release_for_io();
- }
-
- goto next_page;
- }
-
- recv_dblwr.pages.clear();
-
- fil_flush_file_spaces();
- aligned_free(read_buf);
+ space->release();
+ continue;
+ }
+
+ const ulint physical_size= space->physical_size();
+ ut_ad(!buf_is_zeroes(span<const byte>(page, physical_size)));
+
+ /* We want to ensure that for partial reads the unread portion of
+ the page is NUL. */
+ memset(read_buf, 0x0, physical_size);
+
+ /* Read in the actual page from the file */
+ fil_io_t fio= space->io(IORequest(IORequest::DBLWR_RECOVER),
+ os_offset_t{page_no} * physical_size,
+ physical_size, read_buf);
+
+ if (UNIV_UNLIKELY(fio.err != DB_SUCCESS))
+ ib::warn() << "Double write buffer recovery: " << page_id
+ << " (tablespace '" << space->name
+ << "') read failed with error: " << fio.err;
+
+ if (buf_is_zeroes(span<const byte>(read_buf, physical_size)))
+ {
+ /* We will check if the copy in the doublewrite buffer is
+ valid. If not, we will ignore this page (there should be redo
+ log records to initialize it). */
+ }
+ else if (recv_sys.dblwr.validate_page(page_id, read_buf, space, buf))
+ goto next_page;
+ else
+ /* We intentionally skip this message for all-zero pages. */
+ ib::info() << "Trying to recover page " << page_id
+ << " from the doublewrite buffer.";
+
+ page= recv_sys.dblwr.find_page(page_id, space, buf);
+
+ if (!page)
+ goto next_page;
+
+ /* Write the good page from the doublewrite buffer to the intended
+ position. */
+ space->reacquire();
+ fio= space->io(IORequestWrite,
+ os_offset_t{page_id.page_no()} * physical_size,
+ physical_size, page);
+
+ if (fio.err == DB_SUCCESS)
+ ib::info() << "Recovered page " << page_id << " to '" << fio.node->name
+ << "' from the doublewrite buffer.";
+ goto next_page;
+ }
+
+ recv_sys.dblwr.pages.clear();
+ fil_flush_file_spaces();
+ aligned_free(read_buf);
}
-/****************************************************************//**
-Frees doublewrite buffer. */
-void
-buf_dblwr_free()
+/** Free the doublewrite buffer. */
+void buf_dblwr_t::close()
{
- /* Free the double write data structures. */
- ut_a(buf_dblwr != NULL);
- ut_ad(buf_dblwr->s_reserved == 0);
- ut_ad(buf_dblwr->b_reserved == 0);
-
- os_event_destroy(buf_dblwr->b_event);
- os_event_destroy(buf_dblwr->s_event);
- aligned_free(buf_dblwr->write_buf);
- ut_free(buf_dblwr->buf_block_arr);
- mutex_free(&buf_dblwr->mutex);
- ut_free(buf_dblwr);
- buf_dblwr = NULL;
+ if (!is_initialised())
+ return;
+
+ /* Free the double write data structures. */
+ ut_ad(!active_slot->reserved);
+ ut_ad(!active_slot->first_free);
+ ut_ad(!batch_running);
+
+ mysql_cond_destroy(&cond);
+ for (int i= 0; i < 2; i++)
+ {
+ aligned_free(slots[i].write_buf);
+ ut_free(slots[i].buf_block_arr);
+ }
+ mysql_mutex_destroy(&mutex);
+
+ memset((void*) this, 0, sizeof *this);
+ active_slot= &slots[0];
}
/** Update the doublewrite buffer on write completion. */
-void buf_dblwr_update(const buf_page_t &bpage, bool single_page)
+void buf_dblwr_t::write_completed()
{
+ ut_ad(this == &buf_dblwr);
ut_ad(srv_use_doublewrite_buf);
- ut_ad(buf_dblwr);
- ut_ad(!fsp_is_system_temporary(bpage.id().space()));
+ ut_ad(is_initialised());
ut_ad(!srv_read_only_mode);
- if (!single_page)
- {
- mutex_enter(&buf_dblwr->mutex);
-
- ut_ad(buf_dblwr->batch_running);
- ut_ad(buf_dblwr->b_reserved > 0);
- ut_ad(buf_dblwr->b_reserved <= buf_dblwr->first_free);
-
- if (!--buf_dblwr->b_reserved)
- {
- mutex_exit(&buf_dblwr->mutex);
- /* This will finish the batch. Sync data files to the disk. */
- fil_flush_file_spaces();
- mutex_enter(&buf_dblwr->mutex);
-
- /* We can now reuse the doublewrite memory buffer: */
- buf_dblwr->first_free= 0;
- buf_dblwr->batch_running= false;
- os_event_set(buf_dblwr->b_event);
- }
+ mysql_mutex_lock(&mutex);
- mutex_exit(&buf_dblwr->mutex);
- return;
- }
+ ut_ad(batch_running);
+ slot *flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
+ ut_ad(flush_slot->reserved);
+ ut_ad(flush_slot->reserved <= flush_slot->first_free);
- ulint size= TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
- mutex_enter(&buf_dblwr->mutex);
- for (ulint i= srv_doublewrite_batch_size; i < size; ++i)
+ if (!--flush_slot->reserved)
{
- if (buf_dblwr->buf_block_arr[i].bpage != &bpage)
- continue;
- buf_dblwr->s_reserved--;
- buf_dblwr->buf_block_arr[i].bpage= nullptr;
- os_event_set(buf_dblwr->s_event);
- mutex_exit(&buf_dblwr->mutex);
- return;
+ mysql_mutex_unlock(&mutex);
+ /* This will finish the batch. Sync data files to the disk. */
+ fil_flush_file_spaces();
+ mysql_mutex_lock(&mutex);
+
+ /* We can now reuse the doublewrite memory buffer: */
+ flush_slot->first_free= 0;
+ batch_running= false;
+ mysql_cond_broadcast(&cond);
}
- /* The block must exist as a reserved block. */
- ut_error;
+ mysql_mutex_unlock(&mutex);
}
#ifdef UNIV_DEBUG
@@ -718,396 +516,243 @@ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s)
static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page)
{
- if (fil_space_t *space= fil_space_acquire_for_io(b.id().space()))
+ if (fil_space_t *space= fil_space_t::get(b.id().space()))
{
buf_dblwr_check_page_lsn(page, *space);
- space->release_for_io();
+ space->release();
}
}
-#endif /* UNIV_DEBUG */
-/********************************************************************//**
-Asserts when a corrupt block is find during writing out data to the
-disk. */
-static
-void
-buf_dblwr_assert_on_corrupt_block(
-/*==============================*/
- const buf_block_t* block) /*!< in: block to check */
+/** Check the LSN values on the page with which this block is associated. */
+static void buf_dblwr_check_block(const buf_page_t *bpage)
{
- buf_page_print(block->frame);
-
- ib::fatal() << "Apparent corruption of an index page "
- << block->page.id()
- << " to be written to data file. We intentionally crash"
- " the server to prevent corrupt data from ending up in"
- " data files.";
+ ut_ad(bpage->state() == BUF_BLOCK_FILE_PAGE);
+ const page_t *page= reinterpret_cast<const buf_block_t*>(bpage)->frame;
+
+ switch (fil_page_get_type(page)) {
+ case FIL_PAGE_INDEX:
+ case FIL_PAGE_TYPE_INSTANT:
+ case FIL_PAGE_RTREE:
+ if (page_is_comp(page))
+ {
+ if (page_simple_validate_new(page))
+ return;
+ }
+ else if (page_simple_validate_old(page))
+ return;
+ /* While it is possible that this is not an index page but just
+ happens to have wrongly set FIL_PAGE_TYPE, such pages should never
+ be modified to without also adjusting the page type during page
+ allocation or buf_flush_init_for_writing() or
+ fil_block_reset_type(). */
+ buf_page_print(page);
+
+ ib::fatal() << "Apparent corruption of an index page " << bpage->id()
+ << " to be written to data file. We intentionally crash"
+ " the server to prevent corrupt data from ending up in"
+ " data files.";
+ }
}
+#endif /* UNIV_DEBUG */
-/********************************************************************//**
-Check the LSN values on the page with which this block is associated.
-Also validate the page if the option is set. */
-static
-void
-buf_dblwr_check_block(
-/*==================*/
- const buf_block_t* block) /*!< in: block to check */
+bool buf_dblwr_t::flush_buffered_writes(const ulint size)
{
- ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
-
- switch (fil_page_get_type(block->frame)) {
- case FIL_PAGE_INDEX:
- case FIL_PAGE_TYPE_INSTANT:
- case FIL_PAGE_RTREE:
- if (page_is_comp(block->frame)) {
- if (page_simple_validate_new(block->frame)) {
- return;
- }
- } else if (page_simple_validate_old(block->frame)) {
- return;
- }
- /* While it is possible that this is not an index page
- but just happens to have wrongly set FIL_PAGE_TYPE,
- such pages should never be modified to without also
- adjusting the page type during page allocation or
- buf_flush_init_for_writing() or fil_block_reset_type(). */
- break;
- case FIL_PAGE_TYPE_FSP_HDR:
- case FIL_PAGE_IBUF_BITMAP:
- case FIL_PAGE_TYPE_UNKNOWN:
- /* Do not complain again, we already reset this field. */
- case FIL_PAGE_UNDO_LOG:
- case FIL_PAGE_INODE:
- case FIL_PAGE_IBUF_FREE_LIST:
- case FIL_PAGE_TYPE_SYS:
- case FIL_PAGE_TYPE_TRX_SYS:
- case FIL_PAGE_TYPE_XDES:
- case FIL_PAGE_TYPE_BLOB:
- case FIL_PAGE_TYPE_ZBLOB:
- case FIL_PAGE_TYPE_ZBLOB2:
- /* TODO: validate also non-index pages */
- return;
- case FIL_PAGE_TYPE_ALLOCATED:
- /* empty pages should never be flushed */
- return;
- }
-
- buf_dblwr_assert_on_corrupt_block(block);
-}
+ mysql_mutex_assert_owner(&mutex);
+ ut_ad(size == block_size());
-/********************************************************************//**
-Writes a page that has already been written to the doublewrite buffer
-to the datafile. It is the job of the caller to sync the datafile. */
-static void
-buf_dblwr_write_block_to_datafile(const buf_dblwr_t::element &e, bool sync)
-{
- ut_ad(!sync || e.flush == IORequest::SINGLE_PAGE);
- buf_page_t* bpage = e.bpage;
- ut_a(bpage->in_file());
- IORequest request(IORequest::WRITE, bpage, e.flush);
-
- /* We request frame here to get correct buffer in case of
- encryption and/or page compression */
- void * frame = buf_page_get_frame(bpage);
-
- fil_io_t fio;
-
- if (bpage->zip.data) {
- ut_ad(bpage->zip_size());
-
- fio = fil_io(request, sync, bpage->id(), bpage->zip_size(), 0,
- bpage->zip_size(), frame, bpage);
- } else {
- ut_ad(bpage->state() == BUF_BLOCK_FILE_PAGE);
- ut_ad(!bpage->zip_size());
-
- ut_d(buf_dblwr_check_page_lsn(*bpage, static_cast<const byte*>
- (frame)));
- fio = fil_io(request,
- sync, bpage->id(), bpage->zip_size(), 0,
- e.size, frame, bpage);
- }
-
- if (sync && fio.node) {
- ut_ad(fio.err == DB_SUCCESS);
- fio.node->space->release_for_io();
- }
-}
+ for (;;)
+ {
+ if (!active_slot->first_free)
+ return false;
+ if (!batch_running)
+ break;
+ mysql_cond_wait(&cond, &mutex);
+ }
-/********************************************************************//**
-Flushes possible buffered writes from the doublewrite memory buffer to disk.
-It is very important to call this function after a batch of writes has been posted,
-and also when we may have to wait for a page latch! Otherwise a deadlock
-of threads can occur. */
-void
-buf_dblwr_flush_buffered_writes()
-{
- byte* write_buf;
- ulint first_free;
- ulint len;
-
- if (!srv_use_doublewrite_buf || buf_dblwr == NULL) {
- /* Sync the writes to the disk. */
- os_aio_wait_until_no_pending_writes();
- /* Now we flush the data to disk (for example, with fsync) */
- fil_flush_file_spaces();
- return;
- }
-
- ut_ad(!srv_read_only_mode);
-
-try_again:
- mutex_enter(&buf_dblwr->mutex);
-
- /* Write first to doublewrite buffer blocks. We use synchronous
- aio and thus know that file write has been completed when the
- control returns. */
-
- if (buf_dblwr->first_free == 0) {
-
- mutex_exit(&buf_dblwr->mutex);
- return;
- }
-
- if (buf_dblwr->batch_running) {
- /* Another thread is running the batch right now. Wait
- for it to finish. */
- int64_t sig_count = os_event_reset(buf_dblwr->b_event);
- mutex_exit(&buf_dblwr->mutex);
-
- os_event_wait_low(buf_dblwr->b_event, sig_count);
- goto try_again;
- }
-
- ut_ad(buf_dblwr->first_free == buf_dblwr->b_reserved);
-
- /* Disallow anyone else to post to doublewrite buffer or to
- start another batch of flushing. */
- buf_dblwr->batch_running = true;
- first_free = buf_dblwr->first_free;
-
- /* Now safe to release the mutex. Note that though no other
- thread is allowed to post to the doublewrite batch flushing
- but any threads working on single page flushes are allowed
- to proceed. */
- mutex_exit(&buf_dblwr->mutex);
-
- write_buf = buf_dblwr->write_buf;
-
- for (ulint len2 = 0, i = 0;
- i < buf_dblwr->first_free;
- len2 += srv_page_size, i++) {
-
- buf_page_t* bpage= buf_dblwr->buf_block_arr[i].bpage;
-
- if (bpage->state() != BUF_BLOCK_FILE_PAGE || bpage->zip.data) {
- /* No simple validate for compressed
- pages exists. */
- continue;
- }
-
- /* Check that the actual page in the buffer pool is
- not corrupt and the LSN values are sane. */
- buf_dblwr_check_block(reinterpret_cast<buf_block_t*>(bpage));
- ut_d(buf_dblwr_check_page_lsn(*bpage, write_buf + len2));
- }
-
- /* Write out the first block of the doublewrite buffer */
- len = std::min<ulint>(TRX_SYS_DOUBLEWRITE_BLOCK_SIZE,
- buf_dblwr->first_free) << srv_page_size_shift;
-
- fil_io_t fio = fil_io(IORequestWrite, true,
- page_id_t(TRX_SYS_SPACE, buf_dblwr->block1), 0,
- 0, len, write_buf, nullptr);
- fio.node->space->release_for_io();
-
- if (buf_dblwr->first_free <= TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
- /* No unwritten pages in the second block. */
- goto flush;
- }
-
- /* Write out the second block of the doublewrite buffer. */
- len = (buf_dblwr->first_free - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
- << srv_page_size_shift;
-
- write_buf = buf_dblwr->write_buf
- + (TRX_SYS_DOUBLEWRITE_BLOCK_SIZE << srv_page_size_shift);
-
- fio = fil_io(IORequestWrite, true,
- page_id_t(TRX_SYS_SPACE, buf_dblwr->block2), 0,
- 0, len, write_buf, nullptr);
- fio.node->space->release_for_io();
-
-flush:
- /* increment the doublewrite flushed pages counter */
- srv_stats.dblwr_pages_written.add(buf_dblwr->first_free);
- srv_stats.dblwr_writes.inc();
-
- /* Now flush the doublewrite buffer data to disk */
- fil_flush(TRX_SYS_SPACE);
-
- /* We know that the writes have been flushed to disk now
- and in recovery we will find them in the doublewrite buffer
- blocks. Next do the writes to the intended positions. */
-
- /* Up to this point first_free and buf_dblwr->first_free are
- same because we have set the buf_dblwr->batch_running flag
- disallowing any other thread to post any request but we
- can't safely access buf_dblwr->first_free in the loop below.
- This is so because it is possible that after we are done with
- the last iteration and before we terminate the loop, the batch
- gets finished in the IO helper thread and another thread posts
- a new batch setting buf_dblwr->first_free to a higher value.
- If this happens and we are using buf_dblwr->first_free in the
- loop termination condition then we'll end up dispatching
- the same block twice from two different threads. */
- ut_ad(first_free == buf_dblwr->first_free);
- for (ulint i = 0; i < first_free; i++) {
- buf_dblwr_write_block_to_datafile(
- buf_dblwr->buf_block_arr[i], false);
- }
+ ut_ad(active_slot->reserved == active_slot->first_free);
+ ut_ad(!flushing_buffered_writes);
+
+ /* Disallow anyone else to start another batch of flushing. */
+ slot *flush_slot= active_slot;
+ /* Switch the active slot */
+ active_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
+ ut_a(active_slot->first_free == 0);
+ batch_running= true;
+ const ulint old_first_free= flush_slot->first_free;
+ auto write_buf= flush_slot->write_buf;
+ const bool multi_batch= block1 + static_cast<uint32_t>(size) != block2 &&
+ old_first_free > size;
+ flushing_buffered_writes= 1 + multi_batch;
+ /* Now safe to release the mutex. */
+ mysql_mutex_unlock(&mutex);
+#ifdef UNIV_DEBUG
+ for (ulint len2= 0, i= 0; i < old_first_free; len2 += srv_page_size, i++)
+ {
+ buf_page_t *bpage= flush_slot->buf_block_arr[i].request.bpage;
+
+ if (bpage->zip.data)
+ /* No simple validate for ROW_FORMAT=COMPRESSED pages exists. */
+ continue;
+
+ /* Check that the actual page in the buffer pool is not corrupt
+ and the LSN values are sane. */
+ buf_dblwr_check_block(bpage);
+ ut_d(buf_dblwr_check_page_lsn(*bpage, write_buf + len2));
+ }
+#endif /* UNIV_DEBUG */
+ const IORequest request(nullptr, fil_system.sys_space->chain.start,
+ IORequest::DBLWR_BATCH);
+ ut_a(fil_system.sys_space->acquire());
+ if (multi_batch)
+ {
+ fil_system.sys_space->reacquire();
+ os_aio(request, write_buf,
+ os_offset_t{block1.page_no()} << srv_page_size_shift,
+ size << srv_page_size_shift);
+ os_aio(request, write_buf + (size << srv_page_size_shift),
+ os_offset_t{block2.page_no()} << srv_page_size_shift,
+ (old_first_free - size) << srv_page_size_shift);
+ }
+ else
+ os_aio(request, write_buf,
+ os_offset_t{block1.page_no()} << srv_page_size_shift,
+ old_first_free << srv_page_size_shift);
+ srv_stats.data_written.add(old_first_free);
+ return true;
}
-/** Schedule a page write. If the doublewrite memory buffer is full,
-buf_dblwr_flush_buffered_writes() will be invoked to make space.
-@param bpage buffer pool page to be written
-@param flush type of flush
-@param size payload size in bytes */
-void buf_dblwr_t::add_to_batch(buf_page_t *bpage, IORequest::flush_t flush,
- size_t size)
+void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request)
{
- ut_ad(bpage->in_file());
- ut_ad(flush == IORequest::LRU || flush == IORequest::FLUSH_LIST);
+ ut_ad(this == &buf_dblwr);
+ ut_ad(srv_use_doublewrite_buf);
+ ut_ad(is_initialised());
+ ut_ad(!srv_read_only_mode);
+ ut_ad(!request.bpage);
+ ut_ad(request.node == fil_system.sys_space->chain.start);
+ ut_ad(request.type == IORequest::DBLWR_BATCH);
+ mysql_mutex_lock(&mutex);
+ ut_ad(batch_running);
+ ut_ad(flushing_buffered_writes);
+ ut_ad(flushing_buffered_writes <= 2);
+ const bool completed= !--flushing_buffered_writes;
+ mysql_mutex_unlock(&mutex);
+
+ if (!completed)
+ return;
-try_again:
- mutex_enter(&mutex);
+ slot *const flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
+ ut_ad(flush_slot->reserved == flush_slot->first_free);
+ /* increment the doublewrite flushed pages counter */
+ srv_stats.dblwr_pages_written.add(flush_slot->first_free);
+ srv_stats.dblwr_writes.inc();
- ut_a(first_free <= srv_doublewrite_batch_size);
+ /* Now flush the doublewrite buffer data to disk */
+ fil_system.sys_space->flush();
- if (batch_running)
+ /* The writes have been flushed to disk now and in recovery we will
+ find them in the doublewrite buffer blocks. Next, write the data pages. */
+ for (ulint i= 0, first_free= flush_slot->first_free; i < first_free; i++)
{
- /* This not nearly as bad as it looks. There is only page_cleaner
- thread which does background flushing in batches therefore it is
- unlikely to be a contention point. The only exception is when a
- user thread is forced to do a flush batch because of a sync
- checkpoint. */
- int64_t sig_count= os_event_reset(b_event);
- mutex_exit(&mutex);
-
- os_event_wait_low(b_event, sig_count);
- goto try_again;
- }
+ auto e= flush_slot->buf_block_arr[i];
+ buf_page_t* bpage= e.request.bpage;
+ ut_ad(bpage->in_file());
- if (first_free == srv_doublewrite_batch_size)
- {
- mutex_exit(&mutex);
- buf_dblwr_flush_buffered_writes();
- goto try_again;
- }
+ /* We request frame here to get correct buffer in case of
+ encryption and/or page compression */
+ void *frame= buf_page_get_frame(bpage);
- byte *p= write_buf + srv_page_size * first_free;
+ auto e_size= e.size;
- /* We request frame here to get correct buffer in case of
- encryption and/or page compression */
- void * frame = buf_page_get_frame(bpage);
+ if (UNIV_LIKELY_NULL(bpage->zip.data))
+ {
+ e_size= bpage->zip_size();
+ ut_ad(e_size);
+ }
+ else
+ {
+ ut_ad(bpage->state() == BUF_BLOCK_FILE_PAGE);
+ ut_ad(!bpage->zip_size());
+ ut_d(buf_dblwr_check_page_lsn(*bpage, static_cast<const byte*>(frame)));
+ }
- memcpy_aligned<OS_FILE_LOG_BLOCK_SIZE>(p, frame, size);
- ut_ad(!bpage->zip_size() || bpage->zip_size() == size);
- buf_block_arr[first_free++] = { bpage, flush, size };
- b_reserved++;
+ e.request.node->space->io(e.request, bpage->physical_offset(), e_size,
+ frame, bpage);
+ }
+}
- ut_ad(!batch_running);
- ut_ad(first_free == b_reserved);
- ut_ad(b_reserved <= srv_doublewrite_batch_size);
+/** Flush possible buffered writes to persistent storage.
+It is very important to call this function after a batch of writes has been
+posted, and also when we may have to wait for a page latch!
+Otherwise a deadlock of threads can occur. */
+void buf_dblwr_t::flush_buffered_writes()
+{
+ if (!is_initialised() || !srv_use_doublewrite_buf)
+ {
+ os_aio_wait_until_no_pending_writes();
+ fil_flush_file_spaces();
+ return;
+ }
- const bool need_flush= first_free == srv_doublewrite_batch_size;
- mutex_exit(&mutex);
+ ut_ad(!srv_read_only_mode);
+ const ulint size= block_size();
- if (need_flush)
- buf_dblwr_flush_buffered_writes();
+ mysql_mutex_lock(&mutex);
+ if (!flush_buffered_writes(size))
+ mysql_mutex_unlock(&mutex);
}
-/** Write a page to the doublewrite buffer on disk, sync it, then write
-the page to the datafile and sync the datafile. This function is used
-for single page flushes. If all the buffers allocated for single page
-flushes in the doublewrite buffer are in use we wait here for one to
-become free. We are guaranteed that a slot will become free because any
-thread that is using a slot must also release the slot before leaving
-this function.
-@param bpage buffer pool page to be written
-@param sync whether synchronous operation is requested
-@param size payload size in bytes */
-void buf_dblwr_t::write_single_page(buf_page_t *bpage, bool sync, size_t size)
+/** Schedule a page write. If the doublewrite memory buffer is full,
+flush_buffered_writes() will be invoked to make space.
+@param request asynchronous write request
+@param size payload size in bytes */
+void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size)
{
- ut_ad(bpage->in_file());
- ut_ad(srv_use_doublewrite_buf);
- ut_ad(this == buf_dblwr);
+ ut_ad(request.is_async());
+ ut_ad(request.is_write());
+ ut_ad(request.bpage);
+ ut_ad(request.bpage->in_file());
+ ut_ad(request.node);
+ ut_ad(request.node->space->id == request.bpage->id().space());
+ ut_ad(request.node->space->referenced());
+ ut_ad(!srv_read_only_mode);
- /* total number of slots available for single page flushes
- starts from srv_doublewrite_batch_size to the end of the buffer. */
- ulint slots = TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
- ut_a(slots > srv_doublewrite_batch_size);
- ulint n_slots= slots - srv_doublewrite_batch_size;
+ const ulint buf_size= 2 * block_size();
- if (bpage->state() == BUF_BLOCK_FILE_PAGE)
- {
- /* Check that the actual page in the buffer pool is not corrupt
- and the LSN values are sane. */
- buf_dblwr_check_block(reinterpret_cast<buf_block_t*>(bpage));
-#ifdef UNIV_DEBUG
- /* Check that the page as written to the doublewrite buffer has
- sane LSN values. */
- if (!bpage->zip.data)
- buf_dblwr_check_page_lsn(*bpage, reinterpret_cast<buf_block_t*>
- (bpage)->frame);
-#endif
- }
+ mysql_mutex_lock(&mutex);
-retry:
- mutex_enter(&mutex);
- if (s_reserved == n_slots)
+ for (;;)
{
- /* All slots are reserved. */
- int64_t sig_count = os_event_reset(s_event);
- mutex_exit(&mutex);
- os_event_wait_low(s_event, sig_count);
- goto retry;
- }
-
- ulint i;
- for (i = srv_doublewrite_batch_size; i < slots; ++i)
- if (!buf_block_arr[i].bpage)
- goto found;
- /* We are guaranteed to find a slot. */
- ut_error;
-found:
- s_reserved++;
- buf_block_arr[i]= { bpage, IORequest::SINGLE_PAGE, size };
-
- /* increment the doublewrite flushed pages counter */
- srv_stats.dblwr_pages_written.inc();
- srv_stats.dblwr_writes.inc();
+ ut_ad(active_slot->first_free <= buf_size);
+ if (active_slot->first_free != buf_size)
+ break;
- mutex_exit(&mutex);
+ if (flush_buffered_writes(buf_size / 2))
+ mysql_mutex_lock(&mutex);
+ }
- const ulint offset= i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
- ? block1 + i
- : block2 + i - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
+ byte *p= active_slot->write_buf + srv_page_size * active_slot->first_free;
/* We request frame here to get correct buffer in case of
encryption and/or page compression */
- void * frame = buf_page_get_frame(bpage);
- ut_ad(!bpage->zip_size() || bpage->zip_size() == size);
- fil_io_t fio= fil_io(IORequestWrite, true, page_id_t(TRX_SYS_SPACE, offset),
- 0, 0, size, frame, nullptr);
- fio.node->space->release_for_io();
-
- /* Now flush the doublewrite buffer data to disk */
- fil_flush(TRX_SYS_SPACE);
-
- /* We know that the write has been flushed to disk now
- and during recovery we will find it in the doublewrite buffer
- blocks. Next do the write to the intended position. */
- buf_dblwr_write_block_to_datafile({bpage, IORequest::SINGLE_PAGE, size},
- sync);
+ void *frame= buf_page_get_frame(request.bpage);
+
+ /* "frame" is at least 1024-byte aligned for ROW_FORMAT=COMPRESSED pages,
+ and at least srv_page_size (4096-byte) for everything else. */
+ memcpy_aligned<UNIV_ZIP_SIZE_MIN>(p, frame, size);
+ /* fil_page_compress() for page_compressed guarantees 256-byte alignment */
+ memset_aligned<256>(p + size, 0, srv_page_size - size);
+ /* FIXME: Inform the compiler that "size" and "srv_page_size - size"
+ are integer multiples of 256, so the above can translate into simple
+ SIMD instructions. Currently, we make no such assumptions about the
+ non-pointer parameters that are passed to the _aligned templates. */
+ ut_ad(!request.bpage->zip_size() || request.bpage->zip_size() == size);
+ ut_ad(active_slot->reserved == active_slot->first_free);
+ ut_ad(active_slot->reserved < buf_size);
+ new (active_slot->buf_block_arr + active_slot->first_free++)
+ element{request, size};
+ active_slot->reserved= active_slot->first_free;
+
+ if (active_slot->first_free != buf_size ||
+ !flush_buffered_writes(buf_size / 2))
+ mysql_mutex_unlock(&mutex);
}
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index c67273cfec2..037128cbee2 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -280,13 +280,13 @@ buf_dump(
ulint n_pages;
ulint j;
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
n_pages = UT_LIST_GET_LEN(buf_pool.LRU);
/* skip empty buffer pools */
if (n_pages == 0) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
goto done;
}
@@ -314,7 +314,7 @@ buf_dump(
n_pages * sizeof(*dump)));
if (dump == NULL) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
fclose(f);
buf_dump_status(STATUS_ERR,
"Cannot allocate " ULINTPF " bytes: %s",
@@ -339,7 +339,7 @@ buf_dump(
dump[j++] = id;
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
ut_a(j <= n_pages);
n_pages = j;
@@ -493,8 +493,8 @@ buf_load()
page_id_t* dump;
ulint dump_n;
ulint i;
- ulint space_id;
- ulint page_no;
+ uint32_t space_id;
+ uint32_t page_no;
int fscanf_ret;
/* Ignore any leftovers from before */
@@ -518,7 +518,7 @@ buf_load()
This file is tiny (approx 500KB per 1GB buffer pool), reading it
two times is fine. */
dump_n = 0;
- while (fscanf(f, ULINTPF "," ULINTPF, &space_id, &page_no) == 2
+ while (fscanf(f, "%u,%u", &space_id, &page_no) == 2
&& !SHUTTING_DOWN()) {
dump_n++;
}
@@ -569,8 +569,7 @@ buf_load()
export_vars.innodb_buffer_pool_load_incomplete = 1;
for (i = 0; i < dump_n && !SHUTTING_DOWN(); i++) {
- fscanf_ret = fscanf(f, ULINTPF "," ULINTPF,
- &space_id, &page_no);
+ fscanf_ret = fscanf(f, "%u,%u", &space_id, &page_no);
if (fscanf_ret != 2) {
if (feof(f)) {
@@ -592,9 +591,8 @@ buf_load()
fclose(f);
buf_load_status(STATUS_ERR,
"Error parsing '%s': bogus"
- " space,page " ULINTPF "," ULINTPF
- " at line " ULINTPF ","
- " unable to load buffer pool",
+ " space,page %u,%u at line " ULINTPF
+ ", unable to load buffer pool",
full_filename,
space_id, page_no,
i);
@@ -627,11 +625,11 @@ buf_load()
ulint last_check_time = 0;
ulint last_activity_cnt = 0;
- /* Avoid calling the expensive fil_space_acquire_silent() for each
+ /* Avoid calling the expensive fil_space_t::get() for each
page within the same tablespace. dump[] is sorted by (space, page),
so all pages from a given tablespace are consecutive. */
ulint cur_space_id = dump[0].space();
- fil_space_t* space = fil_space_acquire_silent(cur_space_id);
+ fil_space_t* space = fil_space_t::get(cur_space_id);
ulint zip_size = space ? space->zip_size() : 0;
PSI_stage_progress* pfs_stage_progress __attribute__((unused))
@@ -650,31 +648,40 @@ buf_load()
}
if (this_space_id != cur_space_id) {
- if (space != NULL) {
+ if (space) {
space->release();
}
cur_space_id = this_space_id;
- space = fil_space_acquire_silent(cur_space_id);
+ space = fil_space_t::get(cur_space_id);
- if (space != NULL) {
- zip_size = space->zip_size();
+ if (!space) {
+ continue;
}
+
+ zip_size = space->zip_size();
}
/* JAN: TODO: As we use background page read below,
if tablespace is encrypted we cant use it. */
- if (space == NULL ||
- (space && space->crypt_data &&
- space->crypt_data->encryption != FIL_ENCRYPTION_OFF &&
- space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED)) {
+ if (!space || dump[i].page_no() >= space->get_size() ||
+ (space->crypt_data &&
+ space->crypt_data->encryption != FIL_ENCRYPTION_OFF &&
+ space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED)) {
+ continue;
+ }
+
+ if (space->is_stopping()) {
+ space->release();
+ space = nullptr;
continue;
}
- buf_read_page_background(dump[i], zip_size, true);
+ space->reacquire();
+ buf_read_page_background(space, dump[i], zip_size, true);
if (buf_load_abort_flag) {
- if (space != NULL) {
+ if (space) {
space->release();
}
buf_load_abort_flag = false;
@@ -702,7 +709,7 @@ buf_load()
#endif
}
- if (space != NULL) {
+ if (space) {
space->release();
}
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 8f7e2b04782..ac6c45deeab 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -26,6 +26,7 @@ Created 11/11/1995 Heikki Tuuri
*******************************************************/
#include "univ.i"
+#include <my_service_manager.h>
#include <mysql/service_thd_wait.h>
#include <sql_class.h>
@@ -34,20 +35,10 @@ Created 11/11/1995 Heikki Tuuri
#include "buf0checksum.h"
#include "buf0dblwr.h"
#include "srv0start.h"
-#include "srv0srv.h"
#include "page0zip.h"
-#include "ut0byte.h"
-#include "page0page.h"
#include "fil0fil.h"
-#include "buf0lru.h"
-#include "buf0rea.h"
-#include "ibuf0ibuf.h"
-#include "log0log.h"
#include "log0crypt.h"
-#include "os0file.h"
-#include "trx0sys.h"
#include "srv0mon.h"
-#include "ut0stage.h"
#include "fil0pagecompress.h"
#ifdef UNIV_LINUX
/* include defs for CPU time priority settings */
@@ -55,138 +46,46 @@ Created 11/11/1995 Heikki Tuuri
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
-static const int buf_flush_page_cleaner_priority = -20;
#endif /* UNIV_LINUX */
#ifdef HAVE_LZO
-#include "lzo/lzo1x.h"
-#endif
-
-#ifdef HAVE_SNAPPY
-#include "snappy-c.h"
+# include "lzo/lzo1x.h"
+#elif defined HAVE_SNAPPY
+# include "snappy-c.h"
#endif
-/** Sleep time in microseconds for loop waiting for the oldest
-modification lsn */
-static const ulint buf_flush_wait_flushed_sleep_time = 10000;
-
-#include <my_service_manager.h>
-
-/** Number of pages flushed through non flush_list flushes. */
+/** Number of pages flushed via LRU. Protected by buf_pool.mutex.
+Also included in buf_flush_page_count. */
ulint buf_lru_flush_page_count;
-/** Flag indicating if the page_cleaner is in active state. This flag
-is set to TRUE by the page_cleaner thread when it is spawned and is set
-back to FALSE at shutdown by the page_cleaner as well. Therefore no
-need to protect it by a mutex. It is only ever read by the thread
-doing the shutdown */
+/** Number of pages flushed. Protected by buf_pool.mutex. */
+ulint buf_flush_page_count;
+
+/** Flag indicating if the page_cleaner is in active state. */
bool buf_page_cleaner_is_active;
/** Factor for scan length to determine n_pages for intended oldest LSN
progress */
-static ulint buf_flush_lsn_scan_factor = 3;
+static constexpr ulint buf_flush_lsn_scan_factor = 3;
/** Average redo generation rate */
static lsn_t lsn_avg_rate = 0;
-/** Target oldest LSN for the requested flush_sync */
-static lsn_t buf_flush_sync_lsn = 0;
+/** Target oldest_modification for the page cleaner; writes are protected by
+buf_pool.flush_list_mutex */
+static Atomic_relaxed<lsn_t> buf_flush_sync_lsn;
#ifdef UNIV_PFS_THREAD
mysql_pfs_key_t page_cleaner_thread_key;
#endif /* UNIV_PFS_THREAD */
-/** Event to synchronise with the flushing. */
-os_event_t buf_flush_event;
-
-static void pc_flush_slot_func(void *);
-static tpool::task_group page_cleaner_task_group(1);
-static tpool::waitable_task pc_flush_slot_task(
- pc_flush_slot_func, 0, &page_cleaner_task_group);
-
-/** State for page cleaner array slot */
-enum page_cleaner_state_t {
- /** Not requested any yet. Moved from FINISHED. */
- PAGE_CLEANER_STATE_NONE = 0,
- /** Requested but not started flushing. Moved from NONE. */
- PAGE_CLEANER_STATE_REQUESTED,
- /** Flushing is on going. Moved from REQUESTED. */
- PAGE_CLEANER_STATE_FLUSHING,
- /** Flushing was finished. Moved from FLUSHING. */
- PAGE_CLEANER_STATE_FINISHED
-};
-
-/** Page cleaner request state for buf_pool */
-struct page_cleaner_slot_t {
- page_cleaner_state_t state; /*!< state of the request.
- protected by page_cleaner_t::mutex
- if the worker thread got the slot and
- set to PAGE_CLEANER_STATE_FLUSHING,
- n_flushed_lru and n_flushed_list can be
- updated only by the worker thread */
- /* This value is set during state==PAGE_CLEANER_STATE_NONE */
- ulint n_pages_requested;
- /*!< number of requested pages
- for the slot */
- /* These values are updated during state==PAGE_CLEANER_STATE_FLUSHING,
- and commited with state==PAGE_CLEANER_STATE_FINISHED.
- The consistency is protected by the 'state' */
- ulint n_flushed_lru;
- /*!< number of flushed pages
- by LRU scan flushing */
- ulint n_flushed_list;
- /*!< number of flushed pages
- by flush_list flushing */
- bool succeeded_list;
- /*!< true if flush_list flushing
- succeeded. */
- ulint flush_lru_time;
- /*!< elapsed time for LRU flushing */
- ulint flush_list_time;
- /*!< elapsed time for flush_list
- flushing */
- ulint flush_lru_pass;
- /*!< count to attempt LRU flushing */
- ulint flush_list_pass;
- /*!< count to attempt flush_list
- flushing */
-};
-
/** Page cleaner structure */
-struct page_cleaner_t {
- /* FIXME: do we need mutex? use atomics? */
- ib_mutex_t mutex; /*!< mutex to protect whole of
- page_cleaner_t struct and
- page_cleaner_slot_t slots. */
- os_event_t is_finished; /*!< event to signal that all
- slots were finished. */
- bool requested; /*!< true if requested pages
- to flush */
- lsn_t lsn_limit; /*!< upper limit of LSN to be
- flushed */
-#if 1 /* FIXME: use bool for these, or remove some of these */
- ulint n_slots_requested;
- /*!< number of slots
- in the state
- PAGE_CLEANER_STATE_REQUESTED */
- ulint n_slots_flushing;
- /*!< number of slots
- in the state
- PAGE_CLEANER_STATE_FLUSHING */
- ulint n_slots_finished;
- /*!< number of slots
- in the state
- PAGE_CLEANER_STATE_FINISHED */
-#endif
- ulint flush_time; /*!< elapsed time to flush
- requests for all slots */
- ulint flush_pass; /*!< count to finish to flush
- requests for all slots */
- page_cleaner_slot_t slot;
- bool is_running; /*!< false if attempt
- to shutdown */
-};
-
-static page_cleaner_t page_cleaner;
+static struct
+{
+ /** total elapsed time in adaptive flushing, in seconds */
+ ulint flush_time;
+ /** number of adaptive flushing passes */
+ ulint flush_pass;
+} page_cleaner;
#ifdef UNIV_DEBUG
my_bool innodb_page_cleaner_disabled_debug;
@@ -200,15 +99,6 @@ in thrashing. */
/* @} */
-/** Increases flush_list size in bytes with the page size */
-static inline void incr_flush_list_size_in_bytes(const buf_block_t* block)
-{
- /* FIXME: use std::atomic! */
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
- buf_pool.stat.flush_list_bytes += block->physical_size();
- ut_ad(buf_pool.stat.flush_list_bytes <= buf_pool.curr_pool_size);
-}
-
#ifdef UNIV_DEBUG
/** Validate the flush list. */
static void buf_flush_validate_low();
@@ -236,223 +126,122 @@ static void buf_flush_validate_skip()
}
#endif /* UNIV_DEBUG */
-/******************************************************************//**
-Insert a block in the flush_rbt and returns a pointer to its
-predecessor or NULL if no predecessor. The ordering is maintained
-on the basis of the <oldest_modification, space, offset> key.
-@return pointer to the predecessor or NULL if no predecessor. */
-static
-buf_page_t*
-buf_flush_insert_in_flush_rbt(
-/*==========================*/
- buf_page_t* bpage) /*!< in: bpage to be inserted. */
-{
- const ib_rbt_node_t* c_node;
- const ib_rbt_node_t* p_node;
- buf_page_t* prev = NULL;
-
- ut_ad(srv_shutdown_state != SRV_SHUTDOWN_FLUSH_PHASE);
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
-
- /* Insert this buffer into the rbt. */
- c_node = rbt_insert(buf_pool.flush_rbt, &bpage, &bpage);
- ut_a(c_node != NULL);
-
- /* Get the predecessor. */
- p_node = rbt_prev(buf_pool.flush_rbt, c_node);
-
- if (p_node != NULL) {
- buf_page_t** value;
- value = rbt_value(buf_page_t*, p_node);
- prev = *value;
- ut_a(prev != NULL);
- }
-
- return(prev);
-}
-
-/*********************************************************//**
-Delete a bpage from the flush_rbt. */
-static
-void
-buf_flush_delete_from_flush_rbt(
-/*============================*/
- buf_page_t* bpage) /*!< in: bpage to be removed. */
-{
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
-
-#ifdef UNIV_DEBUG
- ibool ret =
-#endif /* UNIV_DEBUG */
- rbt_delete(buf_pool.flush_rbt, &bpage);
-
- ut_ad(ret);
-}
-
-/*****************************************************************//**
-Compare two modified blocks in the buffer pool. The key for comparison
-is:
-key = <oldest_modification, space, offset>
-This comparison is used to maintian ordering of blocks in the
-buf_pool.flush_rbt.
-Note that for the purpose of flush_rbt, we only need to order blocks
-on the oldest_modification. The other two fields are used to uniquely
-identify the blocks.
-@return < 0 if b2 < b1, 0 if b2 == b1, > 0 if b2 > b1 */
-static
-int
-buf_flush_block_cmp(
-/*================*/
- const void* p1, /*!< in: block1 */
- const void* p2) /*!< in: block2 */
-{
- const buf_page_t* b1 = *static_cast<const buf_page_t*const*>(p1);
- const buf_page_t* b2 = *static_cast<const buf_page_t*const*>(p2);
-
- ut_ad(b1 != NULL);
- ut_ad(b2 != NULL);
-
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
-
- const lsn_t m1 = b1->oldest_modification(),
- m2 = b2->oldest_modification();
-
- ut_ad(m1);
- ut_ad(m2);
-
- if (m2 > m1) {
- return(1);
- } else if (m2 < m1) {
- return(-1);
- }
-
- if (b2->id() > b1->id()) {
- return 1;
- }
- if (b2->id() < b1->id()) {
- return -1;
- }
- return 0;
-}
-
-/********************************************************************//**
-Initialize the red-black tree to speed up insertions into the flush_list
-during recovery process. Should be called at the start of recovery
-process before any page has been read/written. */
-void
-buf_flush_init_flush_rbt(void)
-/*==========================*/
-{
- mutex_enter(&buf_pool.flush_list_mutex);
- ut_ad(buf_pool.flush_rbt == NULL);
- /* Create red black tree for speedy insertions in flush list. */
- buf_pool.flush_rbt = rbt_create(
- sizeof(buf_page_t*), buf_flush_block_cmp);
- mutex_exit(&buf_pool.flush_list_mutex);
-}
-
-/********************************************************************//**
-Frees up the red-black tree. */
-void
-buf_flush_free_flush_rbt(void)
-/*==========================*/
-{
- mutex_enter(&buf_pool.flush_list_mutex);
- ut_d(buf_flush_validate_low());
- rbt_free(buf_pool.flush_rbt);
- buf_pool.flush_rbt = NULL;
- mutex_exit(&buf_pool.flush_list_mutex);
-}
-
/** Insert a modified block into the flush list.
@param[in,out] block modified block
@param[in] lsn oldest modification */
void buf_flush_insert_into_flush_list(buf_block_t* block, lsn_t lsn)
{
- ut_ad(!mutex_own(&buf_pool.mutex));
- ut_ad(log_flush_order_mutex_own());
+ mysql_mutex_assert_not_owner(&buf_pool.mutex);
+ mysql_mutex_assert_owner(&log_sys.flush_order_mutex);
ut_ad(lsn);
- mutex_enter(&buf_pool.flush_list_mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
block->page.set_oldest_modification(lsn);
MEM_CHECK_DEFINED(block->page.zip.data
- ? block->page.zip.data : block->frame,
- block->physical_size());
- incr_flush_list_size_in_bytes(block);
-
- if (UNIV_LIKELY_NULL(buf_pool.flush_rbt)) {
- ut_ad(srv_shutdown_state != SRV_SHUTDOWN_FLUSH_PHASE);
- /* The field in_LRU_list is protected by buf_pool.mutex, which
- we are not holding. However, while a block is in the flush
- list, it is dirty and cannot be discarded, not from the
- page_hash or from the LRU list. At most, the uncompressed
- page frame of a compressed block may be discarded or created
- (copying the block->page to or from a buf_page_t that is
- dynamically allocated from buf_buddy_alloc()). Because those
- transitions hold buf_pool.flush_list_mutex (via
- buf_flush_relocate_on_flush_list()), there is no possibility
- of a race condition in the assertions below. */
- ut_ad(block->page.in_LRU_list);
- /* buf_buddy_block_register() will take a block in the
- BUF_BLOCK_MEMORY state, not a file page. */
- ut_ad(!block->page.in_zip_hash);
-
- if (buf_page_t* prev_b =
- buf_flush_insert_in_flush_rbt(&block->page)) {
- UT_LIST_INSERT_AFTER(buf_pool.flush_list, prev_b, &block->page);
- goto func_exit;
- }
- }
+ ? block->page.zip.data : block->frame,
+ block->physical_size());
+ buf_pool.stat.flush_list_bytes += block->physical_size();
+ ut_ad(buf_pool.stat.flush_list_bytes <= buf_pool.curr_pool_size);
UT_LIST_ADD_FIRST(buf_pool.flush_list, &block->page);
-func_exit:
ut_d(buf_flush_validate_skip());
- mutex_exit(&buf_pool.flush_list_mutex);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
/** Remove a block from the flush list of modified blocks.
-@param[in] bpage block to be removed from the flush list */
-void buf_flush_remove(buf_page_t* bpage)
+@param[in,out] bpage block to be removed from the flush list */
+static void buf_flush_remove(buf_page_t *bpage)
{
-#if 0 // FIXME: Rate-limit the output. Move this to the page cleaner?
- if (UNIV_UNLIKELY(srv_shutdown_state == SRV_SHUTDOWN_FLUSH_PHASE)) {
- service_manager_extend_timeout(
- INNODB_EXTEND_TIMEOUT_INTERVAL,
- "Flush and remove page with tablespace id %u"
- ", flush list length " ULINTPF,
- bpage->space, UT_LIST_GET_LEN(buf_pool.flush_list));
- }
-#endif
- ut_ad(mutex_own(&buf_pool.mutex));
- mutex_enter(&buf_pool.flush_list_mutex);
+ mysql_mutex_assert_owner(&buf_pool.mutex);
+ mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
/* Important that we adjust the hazard pointer before removing
the bpage from flush list. */
buf_pool.flush_hp.adjust(bpage);
UT_LIST_REMOVE(buf_pool.flush_list, bpage);
-
- /* If the flush_rbt is active then delete from there as well. */
- if (UNIV_LIKELY_NULL(buf_pool.flush_rbt)) {
- buf_flush_delete_from_flush_rbt(bpage);
- }
-
- /* Must be done after we have removed it from the flush_rbt
- because we assert on it in buf_flush_block_cmp(). */
bpage->clear_oldest_modification();
-#ifdef UNIV_DEBUG
- if (bpage->state() == BUF_BLOCK_ZIP_PAGE) {
- buf_LRU_insert_zip_clean(bpage);
- }
-#endif /* UNIV_DEBUG */
-
buf_pool.stat.flush_list_bytes -= bpage->physical_size();
#ifdef UNIV_DEBUG
buf_flush_validate_skip();
#endif /* UNIV_DEBUG */
+}
+
+/** Remove all dirty pages belonging to a given tablespace when we are
+deleting the data file of that tablespace.
+The pages still remain a part of LRU and are evicted from
+the list as they age towards the tail of the LRU.
+@param id tablespace identifier */
+void buf_flush_remove_pages(ulint id)
+{
+ const page_id_t first(id, 0), end(id + 1, 0);
+ ut_ad(id);
+ mysql_mutex_lock(&buf_pool.mutex);
- mutex_exit(&buf_pool.flush_list_mutex);
+ for (;;)
+ {
+ bool deferred= false;
+
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+
+ for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; )
+ {
+ ut_d(const auto s= bpage->state());
+ ut_ad(s == BUF_BLOCK_ZIP_PAGE || s == BUF_BLOCK_FILE_PAGE ||
+ s == BUF_BLOCK_REMOVE_HASH);
+ buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
+
+ const page_id_t bpage_id(bpage->id());
+
+ if (bpage_id < first || bpage_id >= end);
+ else if (bpage->io_fix() != BUF_IO_NONE)
+ deferred= true;
+ else
+ buf_flush_remove(bpage);
+
+ bpage= prev;
+ }
+
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+
+ if (!deferred)
+ break;
+
+ mysql_mutex_unlock(&buf_pool.mutex);
+ os_thread_yield();
+ mysql_mutex_lock(&buf_pool.mutex);
+ buf_flush_wait_batch_end(false);
+ }
+
+ mysql_mutex_unlock(&buf_pool.mutex);
+}
+
+/** Try to flush all the dirty pages that belong to a given tablespace.
+@param id tablespace identifier
+@return number dirty pages that there were for this tablespace */
+ulint buf_flush_dirty_pages(ulint id)
+{
+ ut_ad(!sync_check_iterate(dict_sync_check()));
+
+ ulint n= 0;
+
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+
+ for (buf_page_t *bpage= UT_LIST_GET_FIRST(buf_pool.flush_list); bpage;
+ bpage= UT_LIST_GET_NEXT(list, bpage))
+ {
+ ut_d(const auto s= bpage->state());
+ ut_ad(s == BUF_BLOCK_ZIP_PAGE || s == BUF_BLOCK_FILE_PAGE ||
+ s == BUF_BLOCK_REMOVE_HASH);
+ ut_ad(bpage->oldest_modification());
+ if (id == bpage->id().space())
+ n++;
+ }
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ if (n)
+ buf_flush_lists(srv_max_io_capacity, LSN_MAX);
+ return n;
}
/*******************************************************************//**
@@ -466,6 +255,7 @@ use the current list node (bpage) to do the list manipulation because
the list pointers could have changed between the time that we copied
the contents of bpage to the dpage and the flush list manipulation
below. */
+ATTRIBUTE_COLD
void
buf_flush_relocate_on_flush_list(
/*=============================*/
@@ -473,10 +263,14 @@ buf_flush_relocate_on_flush_list(
buf_page_t* dpage) /*!< in/out: destination block */
{
buf_page_t* prev;
- buf_page_t* prev_b = NULL;
- ut_ad(mutex_own(&buf_pool.mutex));
- mutex_enter(&buf_pool.flush_list_mutex);
+ mysql_mutex_assert_owner(&buf_pool.mutex);
+
+ if (!bpage->oldest_modification()) {
+ return;
+ }
+
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
/* FIXME: At this point we have both buf_pool and flush_list
mutexes. Theoretically removal of a block from flush list is
@@ -487,19 +281,10 @@ buf_flush_relocate_on_flush_list(
having the buf_pool mutex. */
ut_ad(dpage->oldest_modification());
- /* If recovery is active we must swap the control blocks in
- the flush_rbt as well. */
- if (UNIV_LIKELY_NULL(buf_pool.flush_rbt)) {
- buf_flush_delete_from_flush_rbt(bpage);
- prev_b = buf_flush_insert_in_flush_rbt(dpage);
- }
-
/* Important that we adjust the hazard pointer before removing
the bpage from the flush list. */
buf_pool.flush_hp.adjust(bpage);
- /* Must be done after we have removed it from the flush_rbt
- because we assert on it in buf_flush_block_cmp(). */
bpage->clear_oldest_modification();
prev = UT_LIST_GET_PREV(list, bpage);
@@ -507,59 +292,41 @@ buf_flush_relocate_on_flush_list(
if (prev) {
ut_ad(prev->oldest_modification());
- UT_LIST_INSERT_AFTER( buf_pool.flush_list, prev, dpage);
+ UT_LIST_INSERT_AFTER(buf_pool.flush_list, prev, dpage);
} else {
UT_LIST_ADD_FIRST(buf_pool.flush_list, dpage);
}
- /* Just an extra check. Previous in flush_list
- should be the same control block as in flush_rbt. */
- ut_a(!buf_pool.flush_rbt || prev_b == prev);
ut_d(buf_flush_validate_low());
- mutex_exit(&buf_pool.flush_list_mutex);
-}
-
-/** Update the buf_pool data structures on write completion.
-@param[in,out] bpage written page
-@param[in] flush_type write request type
-@param[in] dblwr whether the doublewrite buffer was used */
-static void buf_flush_write_complete(buf_page_t *bpage,
- IORequest::flush_t flush_type, bool dblwr)
-{
- ut_ad(mutex_own(&buf_pool.mutex));
- buf_flush_remove(bpage);
-
- switch (--buf_pool.n_flush[flush_type]) {
-#ifdef UNIV_DEBUG
- case ULINT_UNDEFINED:
- ut_error;
- break;
-#endif
- case 0:
- if (!buf_pool.init_flush[flush_type])
- os_event_set(buf_pool.no_flush[flush_type]);
- }
-
- if (dblwr)
- buf_dblwr_update(*bpage, flush_type == IORequest::SINGLE_PAGE);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
/** Complete write of a file page from buf_pool.
-@param bpage written page
-@param request write request
-@param dblwr whether the doublewrite buffer was used
-@param evict whether or not to evict the page from LRU list */
-void buf_page_write_complete(buf_page_t *bpage, const IORequest &request,
- bool dblwr, bool evict)
+@param request write request */
+void buf_page_write_complete(const IORequest &request)
{
ut_ad(request.is_write());
+ ut_ad(!srv_read_only_mode/* ||
+ request.node->space->purpose == FIL_TYPE_TEMPORARY*/);
+ buf_page_t *bpage= request.bpage;
+ ut_ad(bpage);
ut_ad(bpage->in_file());
ut_ad(bpage->io_fix() == BUF_IO_WRITE);
- ut_ad(bpage->id().space() != TRX_SYS_SPACE ||
- !buf_dblwr_page_inside(bpage->id().page_no()));
+ ut_ad(!buf_dblwr.is_inside(bpage->id()));
+ bool dblwr;
+ if (bpage->status == buf_page_t::INIT_ON_FLUSH)
+ {
+ bpage->status= buf_page_t::NORMAL;
+ dblwr= false;
+ }
+ else
+ {
+ ut_ad(bpage->status == buf_page_t::NORMAL);
+ dblwr= request.node->space->use_doublewrite();
+ }
/* We do not need protect io_fix here by mutex to read it because
- this and buf_page_write_complete() are the only functions where we can
+ this and buf_page_read_complete() are the only functions where we can
change the value from BUF_IO_READ or BUF_IO_WRITE to some other
value, and our code ensures that this is the only thread that handles
the i/o for this block. */
@@ -573,9 +340,19 @@ void buf_page_write_complete(buf_page_t *bpage, const IORequest &request,
buf_page_monitor(bpage, BUF_IO_WRITE);
DBUG_PRINT("ib_buf", ("write page %u:%u",
bpage->id().space(), bpage->id().page_no()));
- mutex_enter(&buf_pool.mutex);
+ ut_ad(request.is_LRU() ? buf_pool.n_flush_LRU : buf_pool.n_flush_list);
+
+ mysql_mutex_lock(&buf_pool.mutex);
bpage->set_io_fix(BUF_IO_NONE);
- buf_flush_write_complete(bpage, request.flush_type(), dblwr);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ buf_flush_remove(bpage);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+
+ if (dblwr)
+ {
+ ut_ad(!fsp_is_system_temporary(bpage->id().space()));
+ buf_dblwr.write_completed();
+ }
/* Because this thread which does the unlocking might not be the same that
did the locking, we use a pass value != 0 in unlock, which simply
@@ -585,10 +362,19 @@ void buf_page_write_complete(buf_page_t *bpage, const IORequest &request,
buf_pool.stat.n_pages_written++;
- if (evict)
+ if (request.is_LRU())
+ {
buf_LRU_free_page(bpage, true);
+ if (!--buf_pool.n_flush_LRU)
+ mysql_cond_broadcast(&buf_pool.done_flush_LRU);
+ }
+ else
+ {
+ if (!--buf_pool.n_flush_list)
+ mysql_cond_broadcast(&buf_pool.done_flush_list);
+ }
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/** Calculate a ROW_FORMAT=COMPRESSED page checksum and update the page.
@@ -983,72 +769,52 @@ static void buf_release_freed_page(buf_page_t *bpage)
{
ut_ad(bpage->in_file());
const bool uncompressed= bpage->state() == BUF_BLOCK_FILE_PAGE;
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
bpage->set_io_fix(BUF_IO_NONE);
bpage->status= buf_page_t::NORMAL;
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_flush_remove(bpage);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
if (uncompressed)
rw_lock_sx_unlock_gen(&reinterpret_cast<buf_block_t*>(bpage)->lock,
BUF_IO_WRITE);
buf_LRU_free_page(bpage, true);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/** Write a flushable page from buf_pool to a file.
buf_pool.mutex must be held.
@param bpage buffer control block
-@param flush_type type of flush
-@param space tablespace (or nullptr if not known)
-@param sync whether this is a synchronous request
- (only for flush_type=SINGLE_PAGE)
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list
+@param space tablespace
@return whether the page was flushed and buf_pool.mutex was released */
-bool buf_flush_page(buf_page_t *bpage, IORequest::flush_t flush_type,
- fil_space_t *space, bool sync)
+static bool buf_flush_page(buf_page_t *bpage, bool lru, fil_space_t *space)
{
ut_ad(bpage->in_file());
ut_ad(bpage->ready_for_flush());
- ut_ad(!sync || flush_type == IORequest::SINGLE_PAGE);
- ut_ad(mutex_own(&buf_pool.mutex));
+ ut_ad((space->purpose == FIL_TYPE_TEMPORARY) ==
+ (space == fil_system.temp_space));
+ ut_ad(space->purpose == FIL_TYPE_TABLESPACE ||
+ space->atomic_write_supported);
+ ut_ad(space->referenced());
rw_lock_t *rw_lock;
- bool no_fix_count= bpage->buf_fix_count() == 0;
if (bpage->state() != BUF_BLOCK_FILE_PAGE)
rw_lock= nullptr;
- else if (!(no_fix_count || flush_type == IORequest::FLUSH_LIST) ||
- (!no_fix_count && srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP &&
- fsp_is_system_temporary(bpage->id().space())))
- /* This is a heuristic, to avoid expensive SX attempts. */
- /* For table residing in temporary tablespace sync is done
- using IO_FIX and so before scheduling for flush ensure that
- page is not fixed. */
- return false;
else
{
rw_lock= &reinterpret_cast<buf_block_t*>(bpage)->lock;
- if (flush_type != IORequest::FLUSH_LIST &&
- !rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE))
+ if (!rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE))
return false;
}
- /* We are committed to flushing by the time we get here */
bpage->set_io_fix(BUF_IO_WRITE);
- mutex_exit(&buf_pool.mutex);
-
- if (flush_type == IORequest::FLUSH_LIST && rw_lock &&
- !rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE))
- {
- if (!fsp_is_system_temporary(bpage->id().space()))
- /* Avoid a potential deadlock with the doublewrite buffer,
- which might be holding another buf_block_t::lock. */
- buf_dblwr_flush_buffered_writes();
- else
- os_aio_wait_until_no_pending_writes();
-
- rw_lock_sx_lock_gen(rw_lock, BUF_IO_WRITE);
- }
+ buf_flush_page_count++;
+ mysql_mutex_unlock(&buf_pool.mutex);
+ mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
/* We are holding rw_lock = buf_block_t::lock in SX mode except if
this is a ROW_FORMAT=COMPRESSED page whose uncompressed page frame
@@ -1057,38 +823,16 @@ bool buf_flush_page(buf_page_t *bpage, IORequest::flush_t flush_type,
Apart from possible rw_lock protection, bpage is also protected by
io_fix and oldest_modification()!=0. Thus, it cannot be relocated in
the buffer pool or removed from flush_list or LRU_list. */
-#if 0 /* rw_lock_own() does not hold because we passed BUF_IO_WRITE above. */
- ut_ad(!rw_lock || rw_lock_own(rw_lock, RW_LOCK_SX));
-#endif
-
- const fil_space_t * const provided_space= space;
- if (!space)
- {
- space= fil_space_acquire_for_io(bpage->id().space());
- if (UNIV_UNLIKELY(!space))
- {
- mutex_enter(&buf_pool.mutex);
- bpage->status= buf_page_t::NORMAL;
- bpage->set_io_fix(BUF_IO_NONE);
- if (rw_lock)
- rw_lock_sx_unlock_gen(rw_lock, BUF_IO_WRITE);
- return false;
- }
- }
- ut_ad((space->purpose == FIL_TYPE_TEMPORARY) ==
- (space == fil_system.temp_space));
-
- const bool full_crc32= space->full_crc32();
- DBUG_PRINT("ib_buf", ("flush %s %u page %u:%u",
- sync ? "sync" : "async", (unsigned) flush_type,
+ DBUG_PRINT("ib_buf", ("%s %u page %u:%u",
+ lru ? "LRU" : "flush_list",
bpage->id().space(), bpage->id().page_no()));
- ut_ad(!mutex_own(&buf_pool.mutex));
- ut_ad(!mutex_own(&buf_pool.flush_list_mutex));
ut_ad(bpage->io_fix() == BUF_IO_WRITE);
ut_ad(bpage->oldest_modification());
ut_ad(bpage->state() ==
(rw_lock ? BUF_BLOCK_FILE_PAGE : BUF_BLOCK_ZIP_PAGE));
+ ut_ad(ULINT_UNDEFINED >
+ (lru ? buf_pool.n_flush_LRU : buf_pool.n_flush_list));
/* Because bpage->status can only be changed while buf_block_t
exists, it cannot be modified for ROW_FORMAT=COMPRESSED pages
@@ -1097,124 +841,89 @@ bool buf_flush_page(buf_page_t *bpage, IORequest::flush_t flush_type,
is protected even if !rw_lock. */
const auto status= bpage->status;
- if (status != buf_page_t::FREED)
- {
- switch (buf_pool.n_flush[flush_type]++) {
- case 0:
- os_event_reset(buf_pool.no_flush[flush_type]);
- break;
-#ifdef UNIV_DEBUG
- case ULINT_UNDEFINED:
- ut_error;
- break;
-#endif
- }
- }
-
+ buf_block_t *block= reinterpret_cast<buf_block_t*>(bpage);
page_t *frame= bpage->zip.data;
- size_t size, orig_size;
- if (UNIV_UNLIKELY(!rw_lock)) /* ROW_FORMAT=COMPRESSED */
+ if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
{
- ut_ad(!space->full_crc32());
- ut_ad(!space->is_compressed()); /* not page_compressed */
- orig_size= size= bpage->zip_size();
- if (status != buf_page_t::FREED)
+ const lsn_t lsn= mach_read_from_8(my_assume_aligned<8>
+ (FIL_PAGE_LSN +
+ (frame ? frame : block->frame)));
+ ut_ad(lsn);
+ ut_ad(lsn >= bpage->oldest_modification());
+ ut_ad(!srv_read_only_mode);
+ if (UNIV_UNLIKELY(lsn > log_sys.get_flushed_lsn()))
{
- buf_flush_update_zip_checksum(frame, orig_size);
- frame= buf_page_encrypt(space, bpage, frame, &size);
+ if (rw_lock)
+ rw_lock_sx_unlock_gen(rw_lock, BUF_IO_WRITE);
+ mysql_mutex_lock(&buf_pool.mutex);
+ bpage->set_io_fix(BUF_IO_NONE);
+ return false;
}
- ut_ad(size == bpage->zip_size());
}
+
+ if (status == buf_page_t::FREED)
+ buf_release_freed_page(&block->page);
else
{
- buf_block_t *block= reinterpret_cast<buf_block_t*>(bpage);
- byte *page= block->frame;
- orig_size= size= block->physical_size();
+ space->reacquire();
+ ut_ad(status == buf_page_t::NORMAL || status == buf_page_t::INIT_ON_FLUSH);
+ size_t size, orig_size;
+ IORequest::Type type= lru ? IORequest::WRITE_LRU : IORequest::WRITE_ASYNC;
- if (status != buf_page_t::FREED)
+ if (UNIV_UNLIKELY(!rw_lock)) /* ROW_FORMAT=COMPRESSED */
+ {
+ ut_ad(!space->full_crc32());
+ ut_ad(!space->is_compressed()); /* not page_compressed */
+ orig_size= size= bpage->zip_size();
+ buf_flush_update_zip_checksum(frame, size);
+ frame= buf_page_encrypt(space, bpage, frame, &size);
+ ut_ad(size == bpage->zip_size());
+ }
+ else
{
- if (full_crc32)
+ byte *page= block->frame;
+ orig_size= size= block->physical_size();
+
+ if (space->full_crc32())
{
/* innodb_checksum_algorithm=full_crc32 is not implemented for
ROW_FORMAT=COMPRESSED pages. */
ut_ad(!frame);
- page= buf_page_encrypt(space, bpage, page, &size);
+ page= buf_page_encrypt(space, bpage, page, &size);
+ buf_flush_init_for_writing(block, page, nullptr, true);
}
-
- buf_flush_init_for_writing(block, page, frame ? &bpage->zip : nullptr,
- full_crc32);
-
- if (!full_crc32)
+ else
+ {
+ buf_flush_init_for_writing(block, page, frame ? &bpage->zip : nullptr,
+ false);
page= buf_page_encrypt(space, bpage, frame ? frame : page, &size);
- }
-
- frame= page;
- }
-
- if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE))
- {
- const lsn_t lsn= mach_read_from_8(frame + FIL_PAGE_LSN);
- ut_ad(lsn);
- ut_ad(lsn >= bpage->oldest_modification());
- ut_ad(!srv_read_only_mode);
- log_write_up_to(lsn, true);
- }
- else
- ut_ad(space->atomic_write_supported);
-
- bool use_doublewrite;
- IORequest request(IORequest::WRITE, bpage, flush_type);
-
- ut_ad(status == bpage->status);
-
- switch (status) {
- default:
- ut_ad(status == buf_page_t::FREED);
- buf_release_freed_page(bpage);
- goto done;
- case buf_page_t::NORMAL:
- use_doublewrite= space->use_doublewrite();
+ }
- if (use_doublewrite)
- {
- ut_ad(!srv_read_only_mode);
- if (flush_type == IORequest::SINGLE_PAGE)
- buf_dblwr->write_single_page(bpage, sync, size);
- else
- buf_dblwr->add_to_batch(bpage, flush_type, size);
- break;
+#if defined HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || defined _WIN32
+ if (size != orig_size && space->punch_hole)
+ type= lru ? IORequest::PUNCH_LRU : IORequest::PUNCH;
+#else
+ DBUG_EXECUTE_IF("ignore_punch_hole",
+ if (size != orig_size && space->punch_hole)
+ type= lru ? IORequest::PUNCH_LRU : IORequest::PUNCH;);
+#endif
+ frame=page;
}
- /* fall through */
- case buf_page_t::INIT_ON_FLUSH:
- use_doublewrite= false;
- if (size != orig_size)
- request.set_punch_hole();
- /* FIXME: pass space to fil_io() */
- fil_io_t fio= fil_io(request, sync, bpage->id(), bpage->zip_size(), 0,
- bpage->physical_size(), frame, bpage);
- ut_ad(!fio.node || fio.node->space == space);
- if (fio.node && sync)
- fio.node->space->release_for_io();
- }
-
- if (sync)
- {
- ut_ad(bpage->io_fix() == BUF_IO_WRITE);
- /* When flushing single page synchronously, we flush the changes
- only for the tablespace we are working on. */
- if (space->purpose != FIL_TYPE_TEMPORARY)
- fil_flush(space);
+ ut_ad(status == bpage->status);
- if (size != orig_size && space->punch_hole)
- request.set_punch_hole();
- buf_page_write_complete(bpage, request, use_doublewrite, true/*evict*/);
+ if (lru)
+ buf_pool.n_flush_LRU++;
+ else
+ buf_pool.n_flush_list++;
+ if (status != buf_page_t::NORMAL || !space->use_doublewrite())
+ space->io(IORequest(type, bpage),
+ bpage->physical_offset(), size, frame, bpage);
+ else
+ buf_dblwr.add_to_batch(IORequest(bpage, space->chain.start, type), size);
}
-done:
- if (!provided_space)
- space->release_for_io();
/* Increment the I/O operation count used for selecting LRU policy. */
buf_LRU_stat_inc_io();
return true;
@@ -1222,15 +931,15 @@ done:
/** Check whether a page can be flushed from the buf_pool.
@param id page identifier
-@param flush LRU or FLUSH_LIST
+@param fold id.fold()
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list
@return whether the page can be flushed */
-static bool buf_flush_check_neighbor(const page_id_t id,
- IORequest::flush_t flush)
+static bool buf_flush_check_neighbor(const page_id_t id, ulint fold, bool lru)
{
- ut_ad(flush == IORequest::LRU || flush == IORequest::FLUSH_LIST);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
+ ut_ad(fold == id.fold());
- buf_page_t *bpage= buf_pool.page_hash_get_low(id, id.fold());
+ buf_page_t *bpage= buf_pool.page_hash_get_low(id, fold);
if (!bpage || buf_pool.watch_is_sentinel(*bpage))
return false;
@@ -1238,21 +947,20 @@ static bool buf_flush_check_neighbor(const page_id_t id,
/* We avoid flushing 'non-old' blocks in an LRU flush, because the
flushed blocks are soon freed */
- return (flush != IORequest::LRU || bpage->is_old()) &&
- bpage->ready_for_flush();
+ return (!lru || bpage->is_old()) && bpage->ready_for_flush();
}
/** Check which neighbors of a page can be flushed from the buf_pool.
@param space tablespace
@param id page identifier of a dirty page
-@param flush LRU or FLUSH_LIST
+@param contiguous whether to consider contiguous areas of pages
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list
@return last page number that can be flushed */
static page_id_t buf_flush_check_neighbors(const fil_space_t &space,
- page_id_t &id,
- IORequest::flush_t flush)
+ page_id_t &id, bool contiguous,
+ bool lru)
{
ut_ad(id.page_no() < space.size);
- ut_ad(flush == IORequest::LRU || flush == IORequest::FLUSH_LIST);
/* When flushed, dirty blocks are searched in neighborhoods of this
size, and flushed along with the original page. */
const ulint s= buf_pool.curr_size / 16;
@@ -1261,13 +969,19 @@ static page_id_t buf_flush_check_neighbors(const fil_space_t &space,
? static_cast<uint32_t>(s) : read_ahead;
page_id_t low= id - (id.page_no() % buf_flush_area);
page_id_t high= low + buf_flush_area;
- high.set_page_no(std::min(high.page_no(),
- static_cast<uint32_t>(space.committed_size - 1)));
+ high.set_page_no(std::min(high.page_no(), space.last_page_number()));
+
+ if (!contiguous)
+ {
+ high= std::max(id + 1, high);
+ id= low;
+ return high;
+ }
/* Determine the contiguous dirty area around id. */
const ulint id_fold= id.fold();
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (id > low)
{
@@ -1275,8 +989,7 @@ static page_id_t buf_flush_check_neighbors(const fil_space_t &space,
for (page_id_t i= id - 1;; --i)
{
fold--;
- ut_ad(i.fold() == fold);
- if (!buf_flush_check_neighbor(i, flush))
+ if (!buf_flush_check_neighbor(i, fold, lru))
{
low= i + 1;
break;
@@ -1292,22 +1005,20 @@ static page_id_t buf_flush_check_neighbors(const fil_space_t &space,
while (++i < high)
{
++fold;
- ut_ad(i.fold() == fold);
- if (!buf_flush_check_neighbor(i, flush))
+ if (!buf_flush_check_neighbor(i, fold, lru))
break;
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
return i;
}
+MY_ATTRIBUTE((nonnull))
/** Write punch-hole or zeroes of the freed ranges when
innodb_immediate_scrub_data_uncompressed from the freed ranges.
-@param[in] space tablespace which contains freed ranges
-@param[in] freed_ranges freed ranges of the page to be flushed */
+@param space tablespace which may contain ranges of freed pages */
static void buf_flush_freed_pages(fil_space_t *space)
{
- ut_ad(space != NULL);
const bool punch_hole= space->punch_hole;
if (!srv_immediate_scrub_data_uncompressed && !punch_hole)
return;
@@ -1326,27 +1037,24 @@ static void buf_flush_freed_pages(fil_space_t *space)
for (const auto &range : freed_ranges)
{
- ulint page_size= space->zip_size();
- if (!page_size)
- page_size= srv_page_size;
+ const ulint physical_size= space->physical_size();
if (punch_hole)
{
- const auto len= (range.last - range.first + 1) * page_size;
- const page_id_t page_id(space->id, range.first);
- fil_io_t fio= fil_io(IORequestWrite, true, page_id, space->zip_size(),
- 0, len, nullptr, nullptr, false, true);
- if (fio.node)
- fio.node->space->release_for_io();
+ space->reacquire();
+ space->io(IORequest(IORequest::PUNCH_RANGE),
+ os_offset_t{range.first} * physical_size,
+ (range.last - range.first + 1) * physical_size,
+ nullptr);
}
else if (srv_immediate_scrub_data_uncompressed)
{
- for (auto i= range.first; i <= range.last; i++)
+ for (os_offset_t i= range.first; i <= range.last; i++)
{
- const page_id_t page_id(space->id, i);
- fil_io(IORequestWrite, false, page_id, space->zip_size(), 0,
- space->zip_size() ? space->zip_size() : srv_page_size,
- const_cast<byte*>(field_ref_zero), nullptr, false, false);
+ space->reacquire();
+ space->io(IORequest(IORequest::WRITE_ASYNC),
+ i * physical_size, physical_size,
+ const_cast<byte*>(field_ref_zero));
}
}
buf_pool.stat.n_pages_written+= (range.last - range.first + 1);
@@ -1355,95 +1063,69 @@ static void buf_flush_freed_pages(fil_space_t *space)
/** Flushes to disk all flushable pages within the flush area
and also write zeroes or punch the hole for the freed ranges of pages.
-@param[in] page_id page id
-@param[in] flush LRU or FLUSH_LIST
-@param[in] n_flushed number of pages flushed so far in this batch
-@param[in] n_to_flush maximum number of pages we are allowed to flush
+@param space tablespace
+@param page_id page identifier
+@param contiguous whether to consider contiguous areas of pages
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list
+@param n_flushed number of pages flushed so far in this batch
+@param n_to_flush maximum number of pages we are allowed to flush
@return number of pages flushed */
-static
-ulint
-buf_flush_try_neighbors(
- const page_id_t page_id,
- IORequest::flush_t flush,
- ulint n_flushed,
- ulint n_to_flush)
+static ulint buf_flush_try_neighbors(fil_space_t *space,
+ const page_id_t page_id,
+ bool contiguous, bool lru,
+ ulint n_flushed, ulint n_to_flush)
{
- ulint count = 0;
-
- ut_ad(flush == IORequest::LRU || flush == IORequest::FLUSH_LIST);
- fil_space_t* space = fil_space_acquire_for_io(page_id.space());
- if (!space) {
- return 0;
- }
-
- /* Flush the freed ranges while flushing the neighbors */
- buf_flush_freed_pages(space);
-
- page_id_t id = page_id;
- page_id_t high = (srv_flush_neighbors != 1
- || UT_LIST_GET_LEN(buf_pool.LRU)
- < BUF_LRU_OLD_MIN_LEN
- || !space->is_rotational())
- ? id + 1 /* Flush the minimum. */
- : buf_flush_check_neighbors(*space, id, flush);
-
- for (; id < high; ++id) {
- buf_page_t* bpage;
-
- if ((count + n_flushed) >= n_to_flush) {
-
- /* We have already flushed enough pages and
- should call it a day. There is, however, one
- exception. If the page whose neighbors we
- are flushing has not been flushed yet then
- we'll try to flush the victim that we
- selected originally. */
- if (id <= page_id) {
- id = page_id;
- } else {
- break;
- }
- }
+ ut_ad(space->id == page_id.space());
- const ulint fold = id.fold();
-
- mutex_enter(&buf_pool.mutex);
+ ulint count= 0;
+ page_id_t id= page_id;
+ page_id_t high= buf_flush_check_neighbors(*space, id, contiguous, lru);
- bpage = buf_pool.page_hash_get_low(id, fold);
+ ut_ad(page_id >= id);
+ ut_ad(page_id < high);
- if (bpage == NULL) {
- mutex_exit(&buf_pool.mutex);
- continue;
- }
-
- ut_a(bpage->in_file());
+ for (ulint id_fold= id.fold(); id < high && !space->is_stopping();
+ ++id, ++id_fold)
+ {
+ if (count + n_flushed >= n_to_flush)
+ {
+ if (id > page_id)
+ break;
+ /* If the page whose neighbors we are flushing has not been
+ flushed yet, we must flush the page that we selected originally. */
+ id= page_id;
+ id_fold= id.fold();
+ }
- /* We avoid flushing 'non-old' blocks in an LRU flush,
- because the flushed blocks are soon freed */
+ mysql_mutex_lock(&buf_pool.mutex);
- if (flush != IORequest::LRU
- || id == page_id || bpage->is_old()) {
- if (bpage->ready_for_flush()
- && (id == page_id || bpage->buf_fix_count() == 0)
- && buf_flush_page(bpage, flush, space, false)) {
- ++count;
- continue;
- }
- }
- mutex_exit(&buf_pool.mutex);
- }
+ if (buf_page_t *bpage= buf_pool.page_hash_get_low(id, id_fold))
+ {
+ ut_ad(bpage->in_file());
+ /* We avoid flushing 'non-old' blocks in an LRU flush,
+ because the flushed blocks are soon freed */
+ if (!lru || id == page_id || bpage->is_old())
+ {
+ if (!buf_pool.watch_is_sentinel(*bpage) &&
+ bpage->ready_for_flush() && buf_flush_page(bpage, lru, space))
+ {
+ ++count;
+ continue;
+ }
+ }
+ }
- space->release_for_io();
+ mysql_mutex_unlock(&buf_pool.mutex);
+ }
- if (count > 1) {
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_FLUSH_NEIGHBOR_TOTAL_PAGE,
- MONITOR_FLUSH_NEIGHBOR_COUNT,
- MONITOR_FLUSH_NEIGHBOR_PAGES,
- (count - 1));
- }
+ if (auto n= count - 1)
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_NEIGHBOR_TOTAL_PAGE,
+ MONITOR_FLUSH_NEIGHBOR_COUNT,
+ MONITOR_FLUSH_NEIGHBOR_PAGES, n);
+ }
- return(count);
+ return count;
}
/*******************************************************************//**
@@ -1460,17 +1142,16 @@ static ulint buf_free_from_unzip_LRU_list_batch(ulint max)
{
ulint scanned = 0;
ulint count = 0;
- ulint free_len = UT_LIST_GET_LEN(buf_pool.free);
- ulint lru_len = UT_LIST_GET_LEN(buf_pool.unzip_LRU);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
buf_block_t* block = UT_LIST_GET_LAST(buf_pool.unzip_LRU);
- while (block != NULL
+ while (block
&& count < max
- && free_len < srv_LRU_scan_depth
- && lru_len > UT_LIST_GET_LEN(buf_pool.LRU) / 10) {
+ && UT_LIST_GET_LEN(buf_pool.free) < srv_LRU_scan_depth
+ && UT_LIST_GET_LEN(buf_pool.unzip_LRU)
+ > UT_LIST_GET_LEN(buf_pool.LRU) / 10) {
++scanned;
if (buf_LRU_free_page(&block->page, false)) {
@@ -1478,14 +1159,12 @@ static ulint buf_free_from_unzip_LRU_list_batch(ulint max)
released and reacquired */
++count;
block = UT_LIST_GET_LAST(buf_pool.unzip_LRU);
- free_len = UT_LIST_GET_LEN(buf_pool.free);
- lru_len = UT_LIST_GET_LEN(buf_pool.unzip_LRU);
} else {
block = UT_LIST_GET_PREV(unzip_LRU, block);
}
}
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
if (scanned) {
MONITOR_INC_VALUE_CUMULATIVE(
@@ -1498,23 +1177,76 @@ static ulint buf_free_from_unzip_LRU_list_batch(ulint max)
return(count);
}
-/** Flush dirty blocks from the end of the LRU list.
-The calling thread is not allowed to own any latches on pages!
+/** Start writing out pages for a tablespace.
+@param id tablespace identifier
+@return tablespace
+@retval nullptr if the pages for this tablespace should be discarded */
+static fil_space_t *buf_flush_space(const uint32_t id)
+{
+ fil_space_t *space= fil_space_t::get(id);
+ if (space)
+ buf_flush_freed_pages(space);
+ return space;
+}
+
+struct flush_counters_t
+{
+ /** number of dirty pages flushed */
+ ulint flushed;
+ /** number of clean pages evicted */
+ ulint evicted;
+};
+
+/** Try to discard a dirty page.
+@param bpage dirty page whose tablespace is not accessible */
+static void buf_flush_discard_page(buf_page_t *bpage)
+{
+ mysql_mutex_assert_owner(&buf_pool.mutex);
+ mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
+ ut_ad(bpage->in_file());
+ ut_ad(bpage->oldest_modification());
+
+ rw_lock_t *rw_lock;
+
+ if (bpage->state() != BUF_BLOCK_FILE_PAGE)
+ rw_lock= nullptr;
+ else
+ {
+ rw_lock= &reinterpret_cast<buf_block_t*>(bpage)->lock;
+ if (!rw_lock_sx_lock_nowait(rw_lock, 0))
+ return;
+ }
+
+ bpage->status= buf_page_t::NORMAL;
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ buf_flush_remove(bpage);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+
+ if (rw_lock)
+ rw_lock_sx_unlock(rw_lock);
+
+ buf_LRU_free_page(bpage, true);
+}
-@param[in] max desired number of blocks to make available
- in the free list (best effort; not guaranteed)
-@param[out] n counts of flushed and evicted pages */
+/** Flush dirty blocks from the end of the LRU list.
+@param max maximum number of blocks to make available in buf_pool.free
+@param n counts of flushed and evicted pages */
static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
{
ulint scanned= 0;
ulint free_limit= srv_LRU_scan_depth;
- n->flushed = 0;
- n->evicted = 0;
- n->unzip_LRU_evicted = 0;
- ut_ad(mutex_own(&buf_pool.mutex));
+
+ mysql_mutex_assert_owner(&buf_pool.mutex);
if (buf_pool.withdraw_target && buf_pool.curr_size < buf_pool.old_size)
free_limit+= buf_pool.withdraw_target - UT_LIST_GET_LEN(buf_pool.withdraw);
+ const auto neighbors= UT_LIST_GET_LEN(buf_pool.LRU) < BUF_LRU_OLD_MIN_LEN
+ ? 0 : srv_flush_neighbors;
+ fil_space_t *space= nullptr;
+ uint32_t last_space_id= FIL_NULL;
+ static_assert(FIL_NULL > SRV_TMP_SPACE_ID, "consistency");
+ static_assert(FIL_NULL > SRV_SPACE_ID_UPPER_BOUND, "consistency");
+
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.LRU);
bpage && n->flushed + n->evicted < max &&
UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN &&
@@ -1536,10 +1268,40 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
/* Block is ready for flush. Dispatch an IO request. The IO
helper thread will put it on free list in IO completion routine. */
const page_id_t page_id(bpage->id());
- mutex_exit(&buf_pool.mutex);
- n->flushed+= buf_flush_try_neighbors(page_id, IORequest::LRU, n->flushed,
- max);
- mutex_enter(&buf_pool.mutex);
+ const uint32_t space_id= page_id.space();
+ if (!space || space->id != space_id)
+ {
+ if (last_space_id != space_id)
+ {
+ if (space)
+ space->release();
+ space= buf_flush_space(space_id);
+ last_space_id= space_id;
+ }
+ else
+ ut_ad(!space);
+ }
+ else if (space->is_stopping())
+ {
+ space->release();
+ space= nullptr;
+ }
+
+ if (!space)
+ buf_flush_discard_page(bpage);
+ else if (neighbors && space->is_rotational())
+ {
+ mysql_mutex_unlock(&buf_pool.mutex);
+ n->flushed+= buf_flush_try_neighbors(space, page_id, neighbors == 1,
+ true, n->flushed, max);
+reacquire_mutex:
+ mysql_mutex_lock(&buf_pool.mutex);
+ }
+ else if (buf_flush_page(bpage, true, space))
+ {
+ ++n->flushed;
+ goto reacquire_mutex;
+ }
}
else
/* Can't evict or dispatch this block. Go to previous. */
@@ -1548,18 +1310,16 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
buf_pool.lru_hp.set(nullptr);
+ if (space)
+ space->release();
+
/* We keep track of all flushes happening as part of LRU flush. When
estimating the desired rate at which flush_list should be flushed,
we factor in this value. */
buf_lru_flush_page_count+= n->flushed;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
- if (n->evicted)
- MONITOR_INC_VALUE_CUMULATIVE(MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
- MONITOR_LRU_BATCH_EVICT_COUNT,
- MONITOR_LRU_BATCH_EVICT_PAGES,
- n->evicted);
if (scanned)
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_LRU_BATCH_SCANNED,
MONITOR_LRU_BATCH_SCANNED_NUM_CALL,
@@ -1569,44 +1329,52 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
/** Flush and move pages from LRU or unzip_LRU list to the free list.
Whether LRU or unzip_LRU is used depends on the state of the system.
-@param[in] max desired number of blocks to make available
- in the free list (best effort; not guaranteed)
-@param[out] n counts of flushed and evicted pages */
-static void buf_do_LRU_batch(ulint max, flush_counters_t* n)
+@param max maximum number of blocks to make available in buf_pool.free
+@return number of flushed pages */
+static ulint buf_do_LRU_batch(ulint max)
{
- n->unzip_LRU_evicted = buf_LRU_evict_from_unzip_LRU()
- ? buf_free_from_unzip_LRU_list_batch(max) : 0;
-
- if (max > n->unzip_LRU_evicted) {
- buf_flush_LRU_list_batch(max - n->unzip_LRU_evicted, n);
- } else {
- n->evicted = 0;
- n->flushed = 0;
- }
+ const ulint n_unzip_LRU_evicted= buf_LRU_evict_from_unzip_LRU()
+ ? buf_free_from_unzip_LRU_list_batch(max)
+ : 0;
+ flush_counters_t n;
+ n.flushed= 0;
+ n.evicted= n_unzip_LRU_evicted;
+ buf_flush_LRU_list_batch(max, &n);
+
+ if (const ulint evicted= n.evicted - n_unzip_LRU_evicted)
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
+ MONITOR_LRU_BATCH_EVICT_COUNT,
+ MONITOR_LRU_BATCH_EVICT_PAGES,
+ evicted);
+ }
- /* Add evicted pages from unzip_LRU to the evicted pages from
- the simple LRU. */
- n->evicted += n->unzip_LRU_evicted;
+ return n.flushed;
}
/** This utility flushes dirty blocks from the end of the flush_list.
The calling thread is not allowed to own any latches on pages!
-@param[in] min_n wished minimum mumber of blocks flushed (it is
-not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit all blocks whose oldest_modification is smaller
-than this should be flushed (if their number does not exceed min_n)
+@param max_n maximum mumber of blocks to flush
+@param lsn once an oldest_modification>=lsn is found, terminate the batch
@return number of blocks for which the write request was queued */
-static ulint buf_do_flush_list_batch(ulint min_n, lsn_t lsn_limit)
+static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn)
{
ulint count= 0;
ulint scanned= 0;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
+
+ const auto neighbors= UT_LIST_GET_LEN(buf_pool.LRU) < BUF_LRU_OLD_MIN_LEN
+ ? 0 : srv_flush_neighbors;
+ fil_space_t *space= nullptr;
+ uint32_t last_space_id= FIL_NULL;
+ static_assert(FIL_NULL > SRV_TMP_SPACE_ID, "consistency");
+ static_assert(FIL_NULL > SRV_SPACE_ID_UPPER_BOUND, "consistency");
/* Start from the end of the list looking for a suitable block to be
flushed. */
- mutex_enter(&buf_pool.flush_list_mutex);
- ulint len = UT_LIST_GET_LEN(buf_pool.flush_list);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ ulint len= UT_LIST_GET_LEN(buf_pool.flush_list);
/* In order not to degenerate this scan to O(n*n) we attempt to
preserve pointer of previous block in the flush list. To do so we
@@ -1614,17 +1382,17 @@ static ulint buf_do_flush_list_batch(ulint min_n, lsn_t lsn_limit)
must check the hazard pointer and if it is removing the same block
then it must reset it. */
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list);
- bpage && len && count < min_n;
+ bpage && len && count < max_n;
bpage= buf_pool.flush_hp.get(), ++scanned, len--)
{
const lsn_t oldest_modification= bpage->oldest_modification();
- if (oldest_modification >= lsn_limit)
+ if (oldest_modification >= lsn)
break;
- ut_a(oldest_modification);
+ ut_ad(oldest_modification);
buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
buf_pool.flush_hp.set(prev);
- mutex_exit(&buf_pool.flush_list_mutex);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
ut_ad(bpage->in_file());
const bool flushed= bpage->ready_for_flush();
@@ -1632,18 +1400,51 @@ static ulint buf_do_flush_list_batch(ulint min_n, lsn_t lsn_limit)
if (flushed)
{
const page_id_t page_id(bpage->id());
- mutex_exit(&buf_pool.mutex);
- count+= buf_flush_try_neighbors(page_id, IORequest::FLUSH_LIST,
- count, min_n);
- mutex_enter(&buf_pool.mutex);
+ const uint32_t space_id= page_id.space();
+ if (!space || space->id != space_id)
+ {
+ if (last_space_id != space_id)
+ {
+ if (space)
+ space->release();
+ space= buf_flush_space(space_id);
+ last_space_id= space_id;
+ }
+ else
+ ut_ad(!space);
+ }
+ else if (space->is_stopping())
+ {
+ space->release();
+ space= nullptr;
+ }
+
+ if (!space)
+ buf_flush_discard_page(bpage);
+ else if (neighbors && space->is_rotational())
+ {
+ mysql_mutex_unlock(&buf_pool.mutex);
+ count+= buf_flush_try_neighbors(space, page_id, neighbors == 1,
+ false, count, max_n);
+reacquire_mutex:
+ mysql_mutex_lock(&buf_pool.mutex);
+ }
+ else if (buf_flush_page(bpage, false, space))
+ {
+ ++count;
+ goto reacquire_mutex;
+ }
}
- mutex_enter(&buf_pool.flush_list_mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
ut_ad(flushed || buf_pool.flush_hp.is_hp(prev));
}
buf_pool.flush_hp.set(nullptr);
- mutex_exit(&buf_pool.flush_list_mutex);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+
+ if (space)
+ space->release();
if (scanned)
MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_BATCH_SCANNED,
@@ -1655,351 +1456,391 @@ static ulint buf_do_flush_list_batch(ulint min_n, lsn_t lsn_limit)
MONITOR_FLUSH_BATCH_COUNT,
MONITOR_FLUSH_BATCH_PAGES,
count);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
return count;
}
-/** This utility flushes dirty blocks from the end of the LRU list or
-flush_list.
-NOTE 1: in the case of an LRU flush the calling thread may own latches to
-pages: to avoid deadlocks, this function must be written so that it cannot
-end up waiting for these latches! NOTE 2: in the case of a flush list flush,
-the calling thread is not allowed to own any latches on pages!
-@param[in] lru true=LRU; false=FLUSH_LIST;
-if !lru, then the caller must not own any latches on pages
-@param[in] min_n wished minimum mumber of blocks flushed (it is
-not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit in the case of !lru all blocks whose
-@param[out] n counts of flushed and evicted pages
-oldest_modification is smaller than this should be flushed (if their number
-does not exceed min_n), otherwise ignored */
-static
-void
-buf_flush_batch(
- bool lru,
- ulint min_n,
- lsn_t lsn_limit,
- flush_counters_t* n)
+/** Wait until a flush batch ends.
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list */
+void buf_flush_wait_batch_end(bool lru)
{
- ut_ad(lru || !sync_check_iterate(dict_sync_check()));
-
- mutex_enter(&buf_pool.mutex);
-
- /* Note: The buffer pool mutex is released and reacquired within
- the flush functions. */
- if (lru) {
- buf_do_LRU_batch(min_n, n);
- } else {
- n->flushed = buf_do_flush_list_batch(min_n, lsn_limit);
- n->evicted = 0;
- }
+ const auto &n_flush= lru ? buf_pool.n_flush_LRU : buf_pool.n_flush_list;
- mutex_exit(&buf_pool.mutex);
-
- DBUG_PRINT("ib_buf",
- (lru ? "LRU flush completed" : "flush_list completed"));
+ if (n_flush)
+ {
+ auto cond= lru ? &buf_pool.done_flush_LRU : &buf_pool.done_flush_list;
+ tpool::tpool_wait_begin();
+ thd_wait_begin(nullptr, THD_WAIT_DISKIO);
+ do
+ mysql_cond_wait(cond, &buf_pool.mutex);
+ while (n_flush);
+ tpool::tpool_wait_end();
+ thd_wait_end(nullptr);
+ mysql_cond_broadcast(cond);
+ }
}
-/******************************************************************//**
-Gather the aggregated stats for both flush list and LRU list flushing.
-@param page_count_flush number of pages flushed from the end of the flush_list
-@param page_count_LRU number of pages flushed from the end of the LRU list
-*/
-static
-void
-buf_flush_stats(
-/*============*/
- ulint page_count_flush,
- ulint page_count_LRU)
-{
- DBUG_PRINT("ib_buf", ("flush completed, from flush_list %u pages, "
- "from LRU_list %u pages",
- unsigned(page_count_flush),
- unsigned(page_count_LRU)));
+/** Whether a background log flush is pending */
+static std::atomic_flag log_flush_pending;
- srv_stats.buf_pool_flushed.add(page_count_flush + page_count_LRU);
+/** Advance log_sys.get_flushed_lsn() */
+static void log_flush(void *)
+{
+ /* Between batches, we try to prevent I/O stalls by these calls.
+ This should not be needed for correctness. */
+ os_aio_wait_until_no_pending_writes();
+ fil_flush_file_spaces();
+
+ /* Guarantee progress for buf_flush_lists(). */
+ log_write_up_to(log_sys.get_lsn(), true);
+ log_flush_pending.clear();
}
-/** Start a buffer flush batch for LRU or flush list
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list
-@return whether the flush batch was started (was not already running) */
-static bool buf_flush_start(bool lru)
+static tpool::waitable_task log_flush_task(log_flush, nullptr, nullptr);
+
+/** Write out dirty blocks from buf_pool.flush_list.
+@param max_n wished maximum mumber of blocks flushed
+@param lsn buf_pool.get_oldest_modification(LSN_MAX) target (0=LRU flush)
+@return the number of processed pages
+@retval 0 if a batch of the same type (lsn==0 or lsn!=0) is already running */
+ulint buf_flush_lists(ulint max_n, lsn_t lsn)
{
- IORequest::flush_t flush_type= lru ? IORequest::LRU : IORequest::FLUSH_LIST;
- mutex_enter(&buf_pool.mutex);
+ auto &n_flush= lsn ? buf_pool.n_flush_list : buf_pool.n_flush_LRU;
+
+ if (n_flush)
+ return 0;
- if (buf_pool.n_flush[flush_type] > 0 || buf_pool.init_flush[flush_type])
+ if (log_sys.get_lsn() > log_sys.get_flushed_lsn())
{
- /* There is already a flush batch of the same type running */
- mutex_exit(&buf_pool.mutex);
- return false;
+ log_flush_task.wait();
+ if (log_sys.get_lsn() > log_sys.get_flushed_lsn() &&
+ !log_flush_pending.test_and_set())
+ srv_thread_pool->submit_task(&log_flush_task);
+#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
+ if (UNIV_UNLIKELY(ibuf_debug))
+ log_write_up_to(log_sys.get_lsn(), true);
+#endif
}
- buf_pool.init_flush[flush_type]= true;
- os_event_reset(buf_pool.no_flush[flush_type]);
- mutex_exit(&buf_pool.mutex);
- return true;
-}
+ auto cond= lsn ? &buf_pool.done_flush_list : &buf_pool.done_flush_LRU;
-/** End a buffer flush batch.
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list */
-static void buf_flush_end(bool lru)
-{
- IORequest::flush_t flush_type= lru ? IORequest::LRU : IORequest::FLUSH_LIST;
+ mysql_mutex_lock(&buf_pool.mutex);
+ const bool running= n_flush != 0;
+ /* FIXME: we are performing a dirty read of buf_pool.flush_list.count
+ while not holding buf_pool.flush_list_mutex */
+ if (running || !UT_LIST_GET_LEN(buf_pool.flush_list))
+ {
+ if (!running)
+ mysql_cond_broadcast(cond);
+ mysql_mutex_unlock(&buf_pool.mutex);
+ return 0;
+ }
+ n_flush++;
+
+ ulint n_flushed= lsn
+ ? buf_do_flush_list_batch(max_n, lsn)
+ : buf_do_LRU_batch(max_n);
- mutex_enter(&buf_pool.mutex);
+ const auto n_flushing= --n_flush;
- buf_pool.init_flush[flush_type]= false;
buf_pool.try_LRU_scan= true;
- if (!buf_pool.n_flush[flush_type])
- /* The running flush batch has ended */
- os_event_set(buf_pool.no_flush[flush_type]);
+ mysql_mutex_unlock(&buf_pool.mutex);
- mutex_exit(&buf_pool.mutex);
+ if (!n_flushing)
+ mysql_cond_broadcast(cond);
- if (!srv_read_only_mode)
- buf_dblwr_flush_buffered_writes();
-}
+ buf_dblwr.flush_buffered_writes();
-/** Wait until a flush batch ends.
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list */
-void buf_flush_wait_batch_end(bool lru)
-{
- thd_wait_begin(nullptr, THD_WAIT_DISKIO);
- os_event_wait(buf_pool.no_flush[lru
- ? IORequest::LRU : IORequest::FLUSH_LIST]);
- thd_wait_end(nullptr);
+ DBUG_PRINT("ib_buf", ("%s completed, " ULINTPF " pages",
+ lsn ? "flush_list" : "LRU flush", n_flushed));
+ return n_flushed;
}
-/** Do flushing batch of a given type.
-NOTE: The calling thread is not allowed to own any latches on pages!
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list
-@param[in] min_n wished minimum mumber of blocks flushed
-(it is not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit if !lru, all blocks whose
-oldest_modification is smaller than this should be flushed (if their number
-does not exceed min_n), otherwise ignored
-@param[out] n_processed the number of pages which were processed is
-passed back to caller. Ignored if NULL
-@retval true if a batch was queued successfully.
-@retval false if another batch of same type was already running. */
-bool buf_flush_do_batch(bool lru, ulint min_n, lsn_t lsn_limit,
- flush_counters_t *n)
+
+/** Initiate a log checkpoint, discarding the start of the log.
+@param oldest_lsn the checkpoint LSN
+@param end_lsn log_sys.get_lsn()
+@return true if success, false if a checkpoint write was already running */
+static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
{
- if (n)
- n->flushed= 0;
+ ut_ad(!srv_read_only_mode);
+ mysql_mutex_assert_owner(&log_sys.mutex);
+ ut_ad(oldest_lsn <= end_lsn);
+ ut_ad(end_lsn == log_sys.get_lsn());
+ ut_ad(!recv_no_log_write);
+
+ ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn);
+
+ if (oldest_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT)
+ /* Some log has been written since the previous checkpoint. */;
+ else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
+ /* MariaDB startup expects the redo log file to be logically empty
+ (not even containing a FILE_CHECKPOINT record) after a clean shutdown.
+ Perform an extra checkpoint at shutdown. */;
+ else
+ {
+ /* Do nothing, because nothing was logged (other than a
+ FILE_CHECKPOINT record) since the previous checkpoint. */
+ mysql_mutex_unlock(&log_sys.mutex);
+ return true;
+ }
+
+ /* Repeat the FILE_MODIFY records after the checkpoint, in case some
+ log records between the checkpoint and log_sys.lsn need them.
+ Finally, write a FILE_CHECKPOINT record. Redo log apply expects to
+ see a FILE_CHECKPOINT after the checkpoint, except on clean
+ shutdown, where the log will be empty after the checkpoint.
+
+ It is important that we write out the redo log before any further
+ dirty pages are flushed to the tablespace files. At this point,
+ because we hold log_sys.mutex, mtr_t::commit() in other threads will
+ be blocked, and no pages can be added to the flush lists. */
+ lsn_t flush_lsn= oldest_lsn;
+
+ if (fil_names_clear(flush_lsn, oldest_lsn != end_lsn ||
+ srv_shutdown_state <= SRV_SHUTDOWN_INITIATED))
+ {
+ flush_lsn= log_sys.get_lsn();
+ ut_ad(flush_lsn >= end_lsn + SIZE_OF_FILE_CHECKPOINT);
+ mysql_mutex_unlock(&log_sys.mutex);
+ log_write_up_to(flush_lsn, true, true);
+ mysql_mutex_lock(&log_sys.mutex);
+ if (log_sys.last_checkpoint_lsn >= oldest_lsn)
+ {
+ mysql_mutex_unlock(&log_sys.mutex);
+ return true;
+ }
+ }
+ else
+ ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn);
- if (!buf_flush_start(lru))
+ ut_ad(log_sys.get_flushed_lsn() >= flush_lsn);
+
+ if (log_sys.n_pending_checkpoint_writes)
+ {
+ /* A checkpoint write is running */
+ mysql_mutex_unlock(&log_sys.mutex);
return false;
+ }
- buf_flush_batch(lru, min_n, lsn_limit, n);
- buf_flush_end(lru);
+ log_sys.next_checkpoint_lsn= oldest_lsn;
+ log_write_checkpoint_info(end_lsn);
+ mysql_mutex_assert_not_owner(&log_sys.mutex);
return true;
}
-/** Wait until a flush batch of the given lsn ends
-@param[in] new_oldest target oldest_modified_lsn to wait for */
-void buf_flush_wait_flushed(lsn_t new_oldest)
+/** Make a checkpoint. Note that this function does not flush dirty
+blocks from the buffer pool: it only checks what is lsn of the oldest
+modification in the pool, and writes information about the lsn in
+log file. Use log_make_checkpoint() to flush also the pool.
+@retval true if the checkpoint was or had been made
+@retval false if a checkpoint write was already running */
+static bool log_checkpoint()
{
- for (;;) {
- /* We don't need to wait for fsync of the flushed
- blocks, because anyway we need fsync to make chekpoint.
- So, we don't need to wait for the batch end here. */
-
- mutex_enter(&buf_pool.flush_list_mutex);
-
- buf_page_t* bpage;
- /* FIXME: Keep temporary tablespace pages in a separate flush
- list. We would only need to write out temporary pages if the
- page is about to be evicted from the buffer pool, and the page
- contents is still needed (the page has not been freed). */
- for (bpage = UT_LIST_GET_LAST(buf_pool.flush_list);
- bpage && fsp_is_system_temporary(bpage->id().space());
- bpage = UT_LIST_GET_PREV(list, bpage)) {
- ut_ad(bpage->oldest_modification());
- }
-
- lsn_t oldest = bpage ? bpage->oldest_modification() : 0;
+ if (recv_recovery_is_on())
+ recv_sys.apply(true);
- mutex_exit(&buf_pool.flush_list_mutex);
-
- if (oldest == 0 || oldest >= new_oldest) {
- break;
- }
+ switch (srv_file_flush_method) {
+ case SRV_NOSYNC:
+ case SRV_O_DIRECT_NO_FSYNC:
+ break;
+ default:
+ fil_flush_file_spaces();
+ }
- /* sleep and retry */
- os_thread_sleep(buf_flush_wait_flushed_sleep_time);
+ mysql_mutex_lock(&log_sys.mutex);
+ const lsn_t end_lsn= log_sys.get_lsn();
+ mysql_mutex_lock(&log_sys.flush_order_mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ const lsn_t oldest_lsn= buf_pool.get_oldest_modification(end_lsn);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ mysql_mutex_unlock(&log_sys.flush_order_mutex);
+ return log_checkpoint_low(oldest_lsn, end_lsn);
+}
- MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
- }
+/** Make a checkpoint. */
+ATTRIBUTE_COLD void log_make_checkpoint()
+{
+ buf_flush_wait_flushed(log_sys.get_lsn());
+ while (!log_checkpoint());
}
-/** This utility flushes dirty blocks from the end of the flush list.
-NOTE: The calling thread is not allowed to own any latches on pages!
-@param[in] min_n wished minimum mumber of blocks flushed (it is
-not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit all blocks whose
-oldest_modification is smaller than this should be flushed (if their number
-does not exceed min_n), otherwise ignored
-@param[out] n_processed the number of pages which were processed is
-passed back to caller. Ignored if NULL.
-@retval true if a batch was queued successfully
-@retval false if another batch of same type was already running */
-bool buf_flush_lists(ulint min_n, lsn_t lsn_limit, ulint *n_processed)
+/** Wait until all persistent pages are flushed up to a limit.
+@param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */
+ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
{
- flush_counters_t n;
+ ut_ad(sync_lsn);
+ ut_ad(sync_lsn < LSN_MAX);
+ mysql_mutex_assert_not_owner(&log_sys.mutex);
+ ut_ad(!srv_read_only_mode);
- bool success = buf_flush_do_batch(false, min_n, lsn_limit, &n);
+ if (recv_recovery_is_on())
+ recv_sys.apply(true);
- if (n.flushed) {
- buf_flush_stats(n.flushed, 0);
- }
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
- if (n_processed) {
- *n_processed = n.flushed;
- }
+#if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */
+ if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)
+ ut_d(|| innodb_page_cleaner_disabled_debug))
+ {
+ for (;;)
+ {
+ const lsn_t lsn= buf_pool.get_oldest_modification(sync_lsn);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ if (lsn >= sync_lsn)
+ return;
+ ulint n_pages= buf_flush_lists(srv_max_io_capacity, sync_lsn);
+ buf_flush_wait_batch_end_acquiring_mutex(false);
+ if (n_pages)
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_SYNC_TOTAL_PAGE,
+ MONITOR_FLUSH_SYNC_COUNT,
+ MONITOR_FLUSH_SYNC_PAGES, n_pages);
+ log_checkpoint();
+ }
+ MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ }
+ return;
+ }
+ else if (UNIV_LIKELY(srv_flush_sync))
+#endif
+ {
+ if (buf_flush_sync_lsn < sync_lsn)
+ {
+ buf_flush_sync_lsn= sync_lsn;
+ mysql_cond_signal(&buf_pool.do_flush_list);
+ }
+ }
+
+ while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn)
+ {
+ tpool::tpool_wait_begin();
+ thd_wait_begin(nullptr, THD_WAIT_DISKIO);
+ mysql_cond_wait(&buf_pool.done_flush_list, &buf_pool.flush_list_mutex);
+ thd_wait_end(nullptr);
+ tpool::tpool_wait_end();
- return success;
+ MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
+ }
+
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
-/******************************************************************//**
-This function picks up a single page from the tail of the LRU
-list, flushes it (if it is dirty), removes it from page_hash and LRU
-list and puts it on the free list. It is called from user threads when
-they are unable to find a replaceable page at the tail of the LRU
-list i.e.: when the background LRU flushing in the page_cleaner thread
-is not fast enough to keep pace with the workload.
-@return true if success. */
-bool buf_flush_single_page_from_LRU()
+/** If innodb_flush_sync=ON, initiate a furious flush.
+@param lsn buf_pool.get_oldest_modification(LSN_MAX) target */
+void buf_flush_ahead(lsn_t lsn)
{
- ulint scanned = 0;
- bool freed = false;
+ mysql_mutex_assert_not_owner(&log_sys.mutex);
+ ut_ad(!srv_read_only_mode);
- mutex_enter(&buf_pool.mutex);
+ if (recv_recovery_is_on())
+ recv_sys.apply(true);
- for (buf_page_t* bpage = buf_pool.single_scan_itr.start(); bpage;
- ++scanned, bpage = buf_pool.single_scan_itr.get()) {
+ if (buf_flush_sync_lsn < lsn &&
+ UNIV_LIKELY(srv_flush_sync) && UNIV_LIKELY(buf_page_cleaner_is_active))
+ {
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ if (buf_flush_sync_lsn < lsn)
+ {
+ buf_flush_sync_lsn= lsn;
+ mysql_cond_signal(&buf_pool.do_flush_list);
+ }
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ }
+}
- ut_ad(mutex_own(&buf_pool.mutex));
+/** Wait for pending flushes to complete. */
+void buf_flush_wait_batch_end_acquiring_mutex(bool lru)
+{
+ if (lru ? buf_pool.n_flush_LRU : buf_pool.n_flush_list)
+ {
+ mysql_mutex_lock(&buf_pool.mutex);
+ buf_flush_wait_batch_end(lru);
+ mysql_mutex_unlock(&buf_pool.mutex);
+ }
+}
- buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
- buf_pool.single_scan_itr.set(prev);
+/** Conduct checkpoint-related flushing for innodb_flush_sync=ON,
+and try to initiate checkpoints until the target is met.
+@param lsn minimum value of buf_pool.get_oldest_modification(LSN_MAX) */
+ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
+{
+ ut_ad(!srv_read_only_mode);
- if (!bpage->ready_for_flush()) { // FIXME: ready_for_replace()
- continue;
- }
+ for (;;)
+ {
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
- if (!bpage->buf_fix_count()
- && buf_LRU_free_page(bpage, true)) {
- /* block is ready for eviction i.e., it is
- clean and is not IO-fixed or buffer fixed. */
- freed = true;
- break;
- } else {
- /* Block is ready for flush. Try and dispatch an IO
- request. We'll put it on free list in IO completion
- routine if it is not buffer fixed. The following call
- will release the buf_pool.mutex.
+ if (ulint n_flushed= buf_flush_lists(srv_max_io_capacity, lsn))
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_SYNC_TOTAL_PAGE,
+ MONITOR_FLUSH_SYNC_COUNT,
+ MONITOR_FLUSH_SYNC_PAGES, n_flushed);
+ }
- Note: There is no guarantee that this page has actually
- been freed, only that it has been flushed to disk */
+ /* Attempt to perform a log checkpoint upon completing each batch. */
+ if (recv_recovery_is_on())
+ recv_sys.apply(true);
- freed = buf_flush_page(bpage, IORequest::SINGLE_PAGE,
- nullptr, true);
+ switch (srv_file_flush_method) {
+ case SRV_NOSYNC:
+ case SRV_O_DIRECT_NO_FSYNC:
+ break;
+ default:
+ fil_flush_file_spaces();
+ }
- if (freed) {
- goto found;
- }
- }
- }
+ mysql_mutex_lock(&log_sys.mutex);
+ const lsn_t newest_lsn= log_sys.get_lsn();
+ mysql_mutex_lock(&log_sys.flush_order_mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ lsn_t measure= buf_pool.get_oldest_modification(0);
+ mysql_mutex_unlock(&log_sys.flush_order_mutex);
+ const lsn_t checkpoint_lsn= measure ? measure : newest_lsn;
- mutex_exit(&buf_pool.mutex);
-found:
- if (scanned) {
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_LRU_SINGLE_FLUSH_SCANNED,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_NUM_CALL,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_PER_CALL,
- scanned);
- }
+ if (checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT)
+ {
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ log_checkpoint_low(checkpoint_lsn, newest_lsn);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ measure= buf_pool.get_oldest_modification(LSN_MAX);
+ }
+ else
+ {
+ mysql_mutex_unlock(&log_sys.mutex);
+ if (!measure)
+ measure= LSN_MAX;
+ }
- ut_ad(!mutex_own(&buf_pool.mutex));
- return(freed);
-}
+ mysql_mutex_assert_not_owner(&log_sys.mutex);
-/**
-Clear up the tail of the LRU list.
-Put replaceable pages at the tail of LRU to the free list.
-Flush dirty pages at the tail of LRU to the disk.
-The depth to which we scan each buffer pool is controlled by dynamic
-config parameter innodb_LRU_scan_depth.
-@return total pages flushed */
-static ulint buf_flush_LRU_list()
-{
- ulint scan_depth, withdraw_depth;
- flush_counters_t n;
-
- memset(&n, 0, sizeof(flush_counters_t));
-
- /* srv_LRU_scan_depth can be arbitrarily large value.
- We cap it with current LRU size. */
- mutex_enter(&buf_pool.mutex);
- scan_depth = UT_LIST_GET_LEN(buf_pool.LRU);
- if (buf_pool.curr_size < buf_pool.old_size
- && buf_pool.withdraw_target > 0) {
- withdraw_depth = buf_pool.withdraw_target
- - UT_LIST_GET_LEN(buf_pool.withdraw);
- } else {
- withdraw_depth = 0;
- }
- mutex_exit(&buf_pool.mutex);
- if (withdraw_depth > srv_LRU_scan_depth) {
- scan_depth = ut_min(withdraw_depth, scan_depth);
- } else {
- scan_depth = ut_min(static_cast<ulint>(srv_LRU_scan_depth),
- scan_depth);
- }
- /* Currently one of page_cleaners is the only thread
- that can trigger an LRU flush at the same time.
- So, it is not possible that a batch triggered during
- last iteration is still running, */
- buf_flush_do_batch(true, scan_depth, 0, &n);
+ /* After attempting log checkpoint, check if we have reached our target. */
+ const lsn_t target= buf_flush_sync_lsn;
- return(n.flushed);
-}
+ if (measure >= target)
+ buf_flush_sync_lsn= 0;
-/** Wait for any possible LRU flushes to complete. */
-void buf_flush_wait_LRU_batch_end()
-{
- if (buf_pool.n_flush[IORequest::LRU] || buf_pool.init_flush[IORequest::LRU])
- buf_flush_wait_batch_end(true);
+ /* wake up buf_flush_wait_flushed() */
+ mysql_cond_broadcast(&buf_pool.done_flush_list);
+
+ lsn= std::max(lsn, target);
+
+ if (measure >= lsn)
+ return;
+ }
}
/*********************************************************************//**
Calculates if flushing is required based on number of dirty pages in
the buffer pool.
+@param dirty_pct 100*flush_list.count / (LRU.count + free.count)
@return percent of io_capacity to flush to manage dirty page ratio */
-static
-ulint
-af_get_pct_for_dirty()
+static ulint af_get_pct_for_dirty(double dirty_pct)
{
- const ulint dirty = UT_LIST_GET_LEN(buf_pool.flush_list);
- if (!dirty) {
- /* No pages modified */
- return 0;
- }
-
- /* 1 + is there to avoid division by zero (in case the buffer
- pool (including the flush_list) was emptied while we are
- looking at it) */
- double dirty_pct = 100 * static_cast<double>(dirty)
- / static_cast<double>(1 + UT_LIST_GET_LEN(buf_pool.LRU)
- + UT_LIST_GET_LEN(buf_pool.free));
-
- ut_a(srv_max_dirty_pages_pct_lwm
- <= srv_max_buf_pool_modified_pct);
+ ut_ad(srv_max_dirty_pages_pct_lwm <= srv_max_buf_pool_modified_pct);
if (srv_max_dirty_pages_pct_lwm == 0) {
/* The user has not set the option to preflush dirty
@@ -2010,7 +1851,7 @@ af_get_pct_for_dirty()
innodb_io_capacity. */
return(100);
}
- } else if (dirty_pct >= srv_max_dirty_pages_pct_lwm) {
+ } else {
/* We should start flushing pages gradually. */
return(static_cast<ulint>((dirty_pct * 100)
/ (srv_max_buf_pool_modified_pct + 1)));
@@ -2028,30 +1869,16 @@ af_get_pct_for_lsn(
/*===============*/
lsn_t age) /*!< in: current age of LSN. */
{
- lsn_t max_async_age;
- lsn_t lsn_age_factor;
lsn_t af_lwm = static_cast<lsn_t>(
srv_adaptive_flushing_lwm
- * static_cast<double>(log_get_capacity()) / 100);
+ * static_cast<double>(log_sys.log_capacity) / 100);
if (age < af_lwm) {
/* No adaptive flushing. */
return(0);
}
- max_async_age = log_get_max_modified_age_async();
-
- if (age < max_async_age && !srv_adaptive_flushing) {
- /* We have still not reached the max_async point and
- the user has disabled adaptive flushing. */
- return(0);
- }
-
- /* If we are here then we know that either:
- 1) User has enabled adaptive flushing
- 2) User may have disabled adaptive flushing but we have reached
- max_async_age. */
- lsn_age_factor = (age * 100) / max_async_age;
+ lsn_t lsn_age_factor = (age * 100) / log_sys.max_modified_age_async;
ut_ad(srv_max_io_capacity >= srv_io_capacity);
return static_cast<ulint>(
@@ -2061,47 +1888,40 @@ af_get_pct_for_lsn(
/ 7.5));
}
-/*********************************************************************//**
-This function is called approximately once every second by the
-page_cleaner thread. Based on various factors it decides if there is a
-need to do flushing.
+/** This function is called approximately once every second by the
+page_cleaner thread if innodb_adaptive_flushing=ON.
+Based on various factors it decides if there is a need to do flushing.
@return number of pages recommended to be flushed
-@param last_pages_in the number of pages flushed by the last flush_list
- flushing. */
-static
-ulint
-page_cleaner_flush_pages_recommendation(ulint last_pages_in)
+@param last_pages_in number of pages flushed in previous batch
+@param oldest_lsn buf_pool.get_oldest_modification(0)
+@param dirty_pct 100*flush_list.count / (LRU.count + free.count) */
+static ulint page_cleaner_flush_pages_recommendation(ulint last_pages_in,
+ lsn_t oldest_lsn,
+ double dirty_pct)
{
static lsn_t prev_lsn = 0;
static ulint sum_pages = 0;
static ulint avg_page_rate = 0;
static ulint n_iterations = 0;
static time_t prev_time;
- lsn_t oldest_lsn;
- lsn_t cur_lsn;
- lsn_t age;
lsn_t lsn_rate;
ulint n_pages = 0;
- ulint pct_for_dirty = 0;
- ulint pct_for_lsn = 0;
- ulint pct_total = 0;
- cur_lsn = log_sys.get_lsn();
+ const lsn_t cur_lsn = log_sys.get_lsn();
+ ulint pct_for_dirty = af_get_pct_for_dirty(dirty_pct);
+ ut_ad(oldest_lsn <= cur_lsn);
+ ulint pct_for_lsn = af_get_pct_for_lsn(cur_lsn - oldest_lsn);
+ time_t curr_time = time(nullptr);
- if (prev_lsn == 0) {
- /* First time around. */
+ if (!prev_lsn || !pct_for_lsn) {
+ prev_time = curr_time;
prev_lsn = cur_lsn;
- prev_time = time(NULL);
- return(0);
- }
-
- if (prev_lsn == cur_lsn) {
- return(0);
+ return ulint(double(pct_for_dirty) / 100.0
+ * double(srv_io_capacity));
}
sum_pages += last_pages_in;
- time_t curr_time = time(NULL);
double time_elapsed = difftime(curr_time, prev_time);
/* We update our variables every srv_flushing_avg_loops
@@ -2125,66 +1945,18 @@ page_cleaner_flush_pages_recommendation(ulint last_pages_in)
lsn_avg_rate = (lsn_avg_rate + lsn_rate) / 2;
- /* aggregate stats of all slots */
- mutex_enter(&page_cleaner.mutex);
-
ulint flush_tm = page_cleaner.flush_time;
ulint flush_pass = page_cleaner.flush_pass;
page_cleaner.flush_time = 0;
page_cleaner.flush_pass = 0;
- ulint lru_tm = page_cleaner.slot.flush_lru_time;
- ulint list_tm = page_cleaner.slot.flush_list_time;
- ulint lru_pass = page_cleaner.slot.flush_lru_pass;
- ulint list_pass = page_cleaner.slot.flush_list_pass;
- page_cleaner.slot.flush_lru_time = 0;
- page_cleaner.slot.flush_lru_pass = 0;
- page_cleaner.slot.flush_list_time = 0;
- page_cleaner.slot.flush_list_pass = 0;
- mutex_exit(&page_cleaner.mutex);
-
- /* minimum values are 1, to avoid dividing by zero. */
- if (lru_tm < 1) {
- lru_tm = 1;
- }
- if (list_tm < 1) {
- list_tm = 1;
- }
- if (flush_tm < 1) {
- flush_tm = 1;
+ if (flush_pass) {
+ flush_tm /= flush_pass;
}
- if (lru_pass < 1) {
- lru_pass = 1;
- }
- if (list_pass < 1) {
- list_pass = 1;
- }
- if (flush_pass < 1) {
- flush_pass = 1;
- }
-
- MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_TIME_SLOT,
- list_tm / list_pass);
- MONITOR_SET(MONITOR_LRU_BATCH_FLUSH_AVG_TIME_SLOT,
- lru_tm / lru_pass);
-
- MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_TIME_THREAD,
- list_tm / flush_pass);
- MONITOR_SET(MONITOR_LRU_BATCH_FLUSH_AVG_TIME_THREAD,
- lru_tm / flush_pass);
- MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_TIME_EST,
- flush_tm * list_tm / flush_pass
- / (list_tm + lru_tm));
- MONITOR_SET(MONITOR_LRU_BATCH_FLUSH_AVG_TIME_EST,
- flush_tm * lru_tm / flush_pass
- / (list_tm + lru_tm));
- MONITOR_SET(MONITOR_FLUSH_AVG_TIME, flush_tm / flush_pass);
-
- MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_PASS, list_pass);
- MONITOR_SET(MONITOR_LRU_BATCH_FLUSH_AVG_PASS, lru_pass);
- MONITOR_SET(MONITOR_FLUSH_AVG_PASS, flush_pass);
+ MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_TIME, flush_tm);
+ MONITOR_SET(MONITOR_FLUSH_ADAPTIVE_AVG_PASS, flush_pass);
prev_lsn = cur_lsn;
prev_time = curr_time;
@@ -2194,49 +1966,32 @@ page_cleaner_flush_pages_recommendation(ulint last_pages_in)
sum_pages = 0;
}
- oldest_lsn = buf_pool.get_oldest_modification();
-
- ut_ad(oldest_lsn <= log_get_lsn());
-
- age = cur_lsn > oldest_lsn ? cur_lsn - oldest_lsn : 0;
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
- pct_for_dirty = af_get_pct_for_dirty();
- pct_for_lsn = af_get_pct_for_lsn(age);
-
- pct_total = ut_max(pct_for_dirty, pct_for_lsn);
+ ulint pct_total = std::max(pct_for_dirty, pct_for_lsn);
/* Estimate pages to be flushed for the lsn progress */
lsn_t target_lsn = oldest_lsn
+ lsn_avg_rate * buf_flush_lsn_scan_factor;
ulint pages_for_lsn = 0;
- mutex_enter(&buf_pool.flush_list_mutex);
for (buf_page_t* b = UT_LIST_GET_LAST(buf_pool.flush_list);
b != NULL;
b = UT_LIST_GET_PREV(list, b)) {
if (b->oldest_modification() > target_lsn) {
break;
}
- ++pages_for_lsn;
+ if (++pages_for_lsn >= srv_max_io_capacity) {
+ break;
+ }
}
- mutex_exit(&buf_pool.flush_list_mutex);
-
- mutex_enter(&page_cleaner.mutex);
- ut_ad(page_cleaner.slot.state == PAGE_CLEANER_STATE_NONE);
- page_cleaner.slot.n_pages_requested
- = pages_for_lsn / buf_flush_lsn_scan_factor + 1;
- mutex_exit(&page_cleaner.mutex);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
pages_for_lsn /= buf_flush_lsn_scan_factor;
if (pages_for_lsn < 1) {
pages_for_lsn = 1;
}
- /* Cap the maximum IO capacity that we are going to use by
- max_io_capacity. Limit the value to avoid too quick increase */
- pages_for_lsn = std::min<ulint>(
- pages_for_lsn, srv_max_io_capacity * 2);
-
n_pages = (ulint(double(srv_io_capacity) * double(pct_total) / 100.0)
+ avg_page_rate + pages_for_lsn) / 3;
@@ -2244,21 +1999,6 @@ page_cleaner_flush_pages_recommendation(ulint last_pages_in)
n_pages = srv_max_io_capacity;
}
- mutex_enter(&page_cleaner.mutex);
- ut_ad(page_cleaner.n_slots_requested == 0);
- ut_ad(page_cleaner.n_slots_flushing == 0);
- ut_ad(page_cleaner.n_slots_finished == 0);
-
- /* if REDO has enough of free space,
- don't care about age distribution of pages */
- if (pct_for_lsn > 30) {
- page_cleaner.slot.n_pages_requested *= n_pages
- / pages_for_lsn + 1;
- } else {
- page_cleaner.slot.n_pages_requested = n_pages;
- }
- mutex_exit(&page_cleaner.mutex);
-
MONITOR_SET(MONITOR_FLUSH_N_TO_FLUSH_REQUESTED, n_pages);
MONITOR_SET(MONITOR_FLUSH_N_TO_FLUSH_BY_AGE, pages_for_lsn);
@@ -2271,635 +2011,241 @@ page_cleaner_flush_pages_recommendation(ulint last_pages_in)
return(n_pages);
}
-/*********************************************************************//**
-Puts the page_cleaner thread to sleep if it has finished work in less
-than a second
-@retval 0 wake up by event set,
-@retval OS_SYNC_TIME_EXCEEDED if timeout was exceeded
-@param next_loop_time time when next loop iteration should start
-@param sig_count zero or the value returned by previous call of
- os_event_reset()
-@param cur_time current time as in ut_time_ms() */
-static
-ulint
-pc_sleep_if_needed(
-/*===============*/
- ulint next_loop_time,
- int64_t sig_count,
- ulint cur_time)
-{
- /* No sleep if we are cleaning the buffer pool during the shutdown
- with everything else finished */
- if (srv_shutdown_state == SRV_SHUTDOWN_FLUSH_PHASE)
- return OS_SYNC_TIME_EXCEEDED;
-
- if (next_loop_time > cur_time) {
- /* Get sleep interval in micro seconds. We use
- ut_min() to avoid long sleep in case of wrap around. */
- ulint sleep_us;
-
- sleep_us = ut_min(static_cast<ulint>(1000000),
- (next_loop_time - cur_time) * 1000);
-
- return(os_event_wait_time_low(buf_flush_event,
- sleep_us, sig_count));
- }
-
- return(OS_SYNC_TIME_EXCEEDED);
-}
-
-/**
-Requests for all slots to flush.
-@param min_n wished minimum mumber of blocks flushed
- (it is not guaranteed that the actual number is that big)
-@param lsn_limit in the case of buf_pool.flush_list all blocks whose
- oldest_modification is smaller than this should be flushed
- (if their number does not exceed min_n), otherwise ignored
-*/
-static void pc_request(ulint min_n, lsn_t lsn_limit)
-{
- mutex_enter(&page_cleaner.mutex);
-
- ut_ad(page_cleaner.n_slots_requested == 0);
- ut_ad(page_cleaner.n_slots_flushing == 0);
- ut_ad(page_cleaner.n_slots_finished == 0);
-
- page_cleaner.requested = (min_n > 0);
- page_cleaner.lsn_limit = lsn_limit;
-
- ut_ad(page_cleaner.slot.state == PAGE_CLEANER_STATE_NONE);
-
- if (min_n == 0 || min_n == ULINT_MAX) {
- page_cleaner.slot.n_pages_requested = min_n;
- }
-
- /* page_cleaner.slot.n_pages_requested was already set by
- page_cleaner_flush_pages_recommendation() */
-
- page_cleaner.slot.state = PAGE_CLEANER_STATE_REQUESTED;
-
- page_cleaner.n_slots_requested = 1;
- page_cleaner.n_slots_flushing = 0;
- page_cleaner.n_slots_finished = 0;
-
- mutex_exit(&page_cleaner.mutex);
-}
-
-/**
-Do flush for one slot.
-@return the number of the slots which has not been treated yet. */
-static ulint pc_flush_slot()
-{
- ulint lru_tm = 0;
- ulint list_tm = 0;
- ulint lru_pass = 0;
- ulint list_pass = 0;
-
- mutex_enter(&page_cleaner.mutex);
-
- if (page_cleaner.n_slots_requested) {
- ut_ad(page_cleaner.slot.state == PAGE_CLEANER_STATE_REQUESTED);
- page_cleaner.n_slots_requested--;
- page_cleaner.n_slots_flushing++;
- page_cleaner.slot.state = PAGE_CLEANER_STATE_FLUSHING;
-
- if (UNIV_UNLIKELY(!page_cleaner.is_running)) {
- page_cleaner.slot.n_flushed_lru = 0;
- page_cleaner.slot.n_flushed_list = 0;
- goto finish_mutex;
- }
-
- mutex_exit(&page_cleaner.mutex);
-
- lru_tm = ut_time_ms();
-
- /* Flush pages from end of LRU if required */
- page_cleaner.slot.n_flushed_lru = buf_flush_LRU_list();
-
- lru_tm = ut_time_ms() - lru_tm;
- lru_pass++;
-
- if (UNIV_UNLIKELY(!page_cleaner.is_running)) {
- page_cleaner.slot.n_flushed_list = 0;
- goto finish;
- }
-
- /* Flush pages from flush_list if required */
- if (page_cleaner.requested) {
- flush_counters_t n;
- memset(&n, 0, sizeof(flush_counters_t));
- list_tm = ut_time_ms();
-
- page_cleaner.slot.succeeded_list = buf_flush_do_batch(
- false,
- page_cleaner.slot.n_pages_requested,
- page_cleaner.lsn_limit,
- &n);
-
- page_cleaner.slot.n_flushed_list = n.flushed;
-
- list_tm = ut_time_ms() - list_tm;
- list_pass++;
- } else {
- page_cleaner.slot.n_flushed_list = 0;
- page_cleaner.slot.succeeded_list = true;
- }
-finish:
- mutex_enter(&page_cleaner.mutex);
-finish_mutex:
- page_cleaner.n_slots_flushing--;
- page_cleaner.n_slots_finished++;
- page_cleaner.slot.state = PAGE_CLEANER_STATE_FINISHED;
-
- page_cleaner.slot.flush_lru_time += lru_tm;
- page_cleaner.slot.flush_list_time += list_tm;
- page_cleaner.slot.flush_lru_pass += lru_pass;
- page_cleaner.slot.flush_list_pass += list_pass;
-
- if (page_cleaner.n_slots_requested == 0
- && page_cleaner.n_slots_flushing == 0) {
- os_event_set(page_cleaner.is_finished);
- }
- }
-
- ulint ret = page_cleaner.n_slots_requested;
-
- mutex_exit(&page_cleaner.mutex);
-
- return(ret);
-}
-
-/**
-Wait until all flush requests are finished.
-@param n_flushed_lru number of pages flushed from the end of the LRU list.
-@param n_flushed_list number of pages flushed from the end of the
- flush_list.
-@return true if all flush_list flushing batch were success. */
-static
-bool
-pc_wait_finished(
- ulint* n_flushed_lru,
- ulint* n_flushed_list)
-{
- bool all_succeeded = true;
-
- *n_flushed_lru = 0;
- *n_flushed_list = 0;
-
- os_event_wait(page_cleaner.is_finished);
-
- mutex_enter(&page_cleaner.mutex);
-
- ut_ad(page_cleaner.n_slots_requested == 0);
- ut_ad(page_cleaner.n_slots_flushing == 0);
- ut_ad(page_cleaner.n_slots_finished == 1);
-
- ut_ad(page_cleaner.slot.state == PAGE_CLEANER_STATE_FINISHED);
- page_cleaner.slot.state = PAGE_CLEANER_STATE_NONE;
- *n_flushed_lru = page_cleaner.slot.n_flushed_lru;
- *n_flushed_list = page_cleaner.slot.n_flushed_list;
- all_succeeded = page_cleaner.slot.succeeded_list;
- page_cleaner.slot.n_pages_requested = 0;
-
- page_cleaner.n_slots_finished = 0;
-
- os_event_reset(page_cleaner.is_finished);
-
- mutex_exit(&page_cleaner.mutex);
-
- return(all_succeeded);
-}
-
-#ifdef UNIV_LINUX
-/**
-Set priority for page_cleaner threads.
-@param[in] priority priority intended to set
-@return true if set as intended */
-static
-bool
-buf_flush_page_cleaner_set_priority(
- int priority)
-{
- setpriority(PRIO_PROCESS, (pid_t)syscall(SYS_gettid),
- priority);
- return(getpriority(PRIO_PROCESS, (pid_t)syscall(SYS_gettid))
- == priority);
-}
-#endif /* UNIV_LINUX */
-
-#ifdef UNIV_DEBUG
-/** Loop used to disable the page cleaner thread. */
-static void buf_flush_page_cleaner_disabled_loop()
-{
- while (innodb_page_cleaner_disabled_debug
- && srv_shutdown_state == SRV_SHUTDOWN_NONE
- && page_cleaner.is_running) {
- os_thread_sleep(100000);
- }
-}
-#endif /* UNIV_DEBUG */
-
/******************************************************************//**
page_cleaner thread tasked with flushing dirty pages from the buffer
pools. As of now we'll have only one coordinator.
@return a dummy parameter */
static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*)
{
- my_thread_init();
+ my_thread_init();
#ifdef UNIV_PFS_THREAD
- pfs_register_thread(page_cleaner_thread_key);
+ pfs_register_thread(page_cleaner_thread_key);
#endif /* UNIV_PFS_THREAD */
- ut_ad(!srv_read_only_mode);
+ ut_ad(!srv_read_only_mode);
+ ut_ad(buf_page_cleaner_is_active);
#ifdef UNIV_DEBUG_THREAD_CREATION
- ib::info() << "page_cleaner thread running, id "
- << os_thread_pf(os_thread_get_curr_id());
+ ib::info() << "page_cleaner thread running, id "
+ << os_thread_pf(os_thread_get_curr_id());
#endif /* UNIV_DEBUG_THREAD_CREATION */
#ifdef UNIV_LINUX
- /* linux might be able to set different setting for each thread.
- worth to try to set high priority for page cleaner threads */
- if (buf_flush_page_cleaner_set_priority(
- buf_flush_page_cleaner_priority)) {
-
- ib::info() << "page_cleaner coordinator priority: "
- << buf_flush_page_cleaner_priority;
- } else {
- ib::info() << "If the mysqld execution user is authorized,"
- " page cleaner thread priority can be changed."
- " See the man page of setpriority().";
- }
- /* Signal that setpriority() has been attempted. */
- os_event_set(recv_sys.flush_end);
+ /* linux might be able to set different setting for each thread.
+ worth to try to set high priority for the page cleaner thread */
+ const pid_t tid= static_cast<pid_t>(syscall(SYS_gettid));
+ setpriority(PRIO_PROCESS, tid, -20);
+ if (getpriority(PRIO_PROCESS, tid) != -20)
+ ib::info() << "If the mysqld execution user is authorized,"
+ " page cleaner thread priority can be changed."
+ " See the man page of setpriority().";
#endif /* UNIV_LINUX */
- do {
- /* treat flushing requests during recovery. */
- ulint n_flushed_lru = 0;
- ulint n_flushed_list = 0;
-
- os_event_wait(recv_sys.flush_start);
-
- if (!recv_writer_thread_active) {
- break;
- }
-
- if (recv_sys.flush_lru) {
- /* Flush pages from end of LRU if required */
- pc_request(0, LSN_MAX);
- while (pc_flush_slot() > 0) {}
- pc_wait_finished(&n_flushed_lru, &n_flushed_list);
- } else {
- /* Flush all pages */
- do {
- pc_request(ULINT_MAX, LSN_MAX);
- while (pc_flush_slot() > 0) {}
- } while (!pc_wait_finished(&n_flushed_lru,
- &n_flushed_list));
- }
-
- os_event_reset(recv_sys.flush_start);
- os_event_set(recv_sys.flush_end);
- } while (recv_writer_thread_active);
-
- os_event_wait(buf_flush_event);
-
- ulint ret_sleep = 0;
- ulint n_evicted = 0;
- ulint n_flushed_last = 0;
- ulint warn_interval = 1;
- ulint warn_count = 0;
- int64_t sig_count = os_event_reset(buf_flush_event);
- ulint next_loop_time = ut_time_ms() + 1000;
- ulint n_flushed = 0;
- ulint last_activity = srv_get_activity_count();
- ulint last_pages = 0;
-
- while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
- ulint curr_time = ut_time_ms();
-
- /* The page_cleaner skips sleep if the server is
- idle and there are no pending IOs in the buffer pool
- and there is work to do. */
- if (!n_flushed || !buf_pool.n_pend_reads
- || srv_check_activity(&last_activity)) {
-
- ret_sleep = pc_sleep_if_needed(
- next_loop_time, sig_count, curr_time);
- } else if (curr_time > next_loop_time) {
- ret_sleep = OS_SYNC_TIME_EXCEEDED;
- } else {
- ret_sleep = 0;
- }
-
- if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
- break;
- }
-
- sig_count = os_event_reset(buf_flush_event);
-
- if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
- if (global_system_variables.log_warnings > 2
- && curr_time > next_loop_time + 3000
- && !(test_flags & TEST_SIGINT)) {
- if (warn_count == 0) {
- ib::info() << "page_cleaner: 1000ms"
- " intended loop took "
- << 1000 + curr_time
- - next_loop_time
- << "ms. The settings might not"
- " be optimal. (flushed="
- << n_flushed_last
- << " and evicted="
- << n_evicted
- << ", during the time.)";
- if (warn_interval > 300) {
- warn_interval = 600;
- } else {
- warn_interval *= 2;
- }
-
- warn_count = warn_interval;
- } else {
- --warn_count;
- }
- } else {
- /* reset counter */
- warn_interval = 1;
- warn_count = 0;
- }
-
- next_loop_time = curr_time + 1000;
- n_flushed_last = n_evicted = 0;
- }
-
- if (ret_sleep != OS_SYNC_TIME_EXCEEDED
- && srv_flush_sync
- && buf_flush_sync_lsn > 0) {
- /* woke up for flush_sync */
- mutex_enter(&page_cleaner.mutex);
- lsn_t lsn_limit = buf_flush_sync_lsn;
- buf_flush_sync_lsn = 0;
- mutex_exit(&page_cleaner.mutex);
-
- /* Request flushing for threads */
- pc_request(ULINT_MAX, lsn_limit);
-
- ulint tm = ut_time_ms();
-
- /* Coordinator also treats requests */
- while (pc_flush_slot() > 0) {}
-
- /* only coordinator is using these counters,
- so no need to protect by lock. */
- page_cleaner.flush_time += ut_time_ms() - tm;
- page_cleaner.flush_pass++;
-
- /* Wait for all slots to be finished */
- ulint n_flushed_lru = 0;
- ulint n_flushed_list = 0;
- pc_wait_finished(&n_flushed_lru, &n_flushed_list);
-
- if (n_flushed_list > 0 || n_flushed_lru > 0) {
- buf_flush_stats(n_flushed_list, n_flushed_lru);
-
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_FLUSH_SYNC_TOTAL_PAGE,
- MONITOR_FLUSH_SYNC_COUNT,
- MONITOR_FLUSH_SYNC_PAGES,
- n_flushed_lru + n_flushed_list);
- }
-
- n_flushed = n_flushed_lru + n_flushed_list;
-
- } else if (srv_check_activity(&last_activity)) {
- ulint n_to_flush;
- lsn_t lsn_limit;
-
- /* Estimate pages from flush_list to be flushed */
- if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
- last_activity = srv_get_activity_count();
- n_to_flush =
- page_cleaner_flush_pages_recommendation(
- last_pages);
- lsn_limit = LSN_MAX;
- } else {
- n_to_flush = 0;
- lsn_limit = 0;
- }
-
- /* Request flushing for threads */
- pc_request(n_to_flush, lsn_limit);
-
- ulint tm = ut_time_ms();
-
- /* Coordinator also treats requests */
- while (pc_flush_slot() > 0) {
- /* No op */
- }
-
- /* only coordinator is using these counters,
- so no need to protect by lock. */
- page_cleaner.flush_time += ut_time_ms() - tm;
- page_cleaner.flush_pass++ ;
-
- /* Wait for all slots to be finished */
- ulint n_flushed_lru = 0;
- ulint n_flushed_list = 0;
-
- pc_wait_finished(&n_flushed_lru, &n_flushed_list);
-
- if (n_flushed_list > 0 || n_flushed_lru > 0) {
- buf_flush_stats(n_flushed_list, n_flushed_lru);
- }
-
- if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
- last_pages = n_flushed_list;
- }
+ ulint last_pages= 0;
+ timespec abstime;
+ set_timespec(abstime, 1);
- n_evicted += n_flushed_lru;
- n_flushed_last += n_flushed_list;
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
- n_flushed = n_flushed_lru + n_flushed_list;
+ lsn_t lsn_limit;
- if (n_flushed_lru) {
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE,
- MONITOR_LRU_BATCH_FLUSH_COUNT,
- MONITOR_LRU_BATCH_FLUSH_PAGES,
- n_flushed_lru);
- }
-
- if (n_flushed_list) {
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_FLUSH_ADAPTIVE_TOTAL_PAGE,
- MONITOR_FLUSH_ADAPTIVE_COUNT,
- MONITOR_FLUSH_ADAPTIVE_PAGES,
- n_flushed_list);
- }
-
- } else if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
- /* no activity, slept enough */
- buf_flush_lists(srv_io_capacity, LSN_MAX, &n_flushed);
-
- n_flushed_last += n_flushed;
-
- if (n_flushed) {
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,
- MONITOR_FLUSH_BACKGROUND_COUNT,
- MONITOR_FLUSH_BACKGROUND_PAGES,
- n_flushed);
-
- }
-
- } else {
- /* no activity, but woken up by event */
- n_flushed = 0;
- }
+ for (;;)
+ {
+ lsn_limit= buf_flush_sync_lsn;
- ut_d(buf_flush_page_cleaner_disabled_loop());
- }
+ if (UNIV_UNLIKELY(lsn_limit != 0))
+ {
+furious_flush:
+ buf_flush_sync_for_checkpoint(lsn_limit);
+ last_pages= 0;
+ set_timespec(abstime, 1);
+ continue;
+ }
- ut_ad(srv_shutdown_state > SRV_SHUTDOWN_INITIATED);
- if (srv_fast_shutdown == 2
- || srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- /* In very fast shutdown or when innodb failed to start, we
- simulate a crash of the buffer pool. We are not required to do
- any flushing. */
- goto thread_exit;
- }
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
+ break;
- /* In case of normal and slow shutdown the page_cleaner thread
- must wait for all other activity in the server to die down.
- Note that we can start flushing the buffer pool as soon as the
- server enters shutdown phase but we must stay alive long enough
- to ensure that any work done by the master or purge threads is
- also flushed.
- During shutdown we pass through two stages. In the first stage,
- when SRV_SHUTDOWN_CLEANUP is set other threads like the master
- and the purge threads may be working as well. We start flushing
- the buffer pool but can't be sure that no new pages are being
- dirtied until we enter SRV_SHUTDOWN_FLUSH_PHASE phase. */
+ mysql_cond_timedwait(&buf_pool.do_flush_list, &buf_pool.flush_list_mutex,
+ &abstime);
+ set_timespec(abstime, 1);
- do {
- pc_request(ULINT_MAX, LSN_MAX);
+ lsn_limit= buf_flush_sync_lsn;
- while (pc_flush_slot() > 0) {}
+ if (UNIV_UNLIKELY(lsn_limit != 0))
+ goto furious_flush;
- ulint n_flushed_lru = 0;
- ulint n_flushed_list = 0;
- pc_wait_finished(&n_flushed_lru, &n_flushed_list);
+ if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
+ break;
- n_flushed = n_flushed_lru + n_flushed_list;
+ const ulint dirty_blocks= UT_LIST_GET_LEN(buf_pool.flush_list);
- /* We sleep only if there are no pages to flush */
- if (n_flushed == 0) {
- os_thread_sleep(100000);
- }
- } while (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
+ if (!dirty_blocks)
+ continue;
- /* At this point all threads including the master and the purge
- thread must have been suspended. */
- ut_ad(!srv_any_background_activity());
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_FLUSH_PHASE);
+ /* We perform dirty reads of the LRU+free list lengths here.
+ Division by zero is not possible, because buf_pool.flush_list is
+ guaranteed to be nonempty, and it is a subset of buf_pool.LRU. */
+ const double dirty_pct= double(dirty_blocks) * 100.0 /
+ double(UT_LIST_GET_LEN(buf_pool.LRU) + UT_LIST_GET_LEN(buf_pool.free));
- /* We can now make a final sweep on flushing the buffer pool
- and exit after we have cleaned the whole buffer pool.
- It is important that we wait for any running batch that has
- been triggered by us to finish. Otherwise we can end up
- considering end of that batch as a finish of our final
- sweep and we'll come out of the loop leaving behind dirty pages
- in the flush_list */
- buf_flush_wait_batch_end(false);
- buf_flush_wait_LRU_batch_end();
+ if (dirty_pct < srv_max_dirty_pages_pct_lwm)
+ continue;
- bool success;
+ const lsn_t oldest_lsn= buf_pool.get_oldest_modification(0);
- do {
- pc_request(ULINT_MAX, LSN_MAX);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
- while (pc_flush_slot() > 0) {}
+ ulint n_flushed;
- ulint n_flushed_lru = 0;
- ulint n_flushed_list = 0;
- success = pc_wait_finished(&n_flushed_lru, &n_flushed_list);
+ if (!srv_adaptive_flushing)
+ {
+ n_flushed= buf_flush_lists(srv_io_capacity, LSN_MAX);
- n_flushed = n_flushed_lru + n_flushed_list;
+ if (n_flushed)
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,
+ MONITOR_FLUSH_BACKGROUND_COUNT,
+ MONITOR_FLUSH_BACKGROUND_PAGES,
+ n_flushed);
+do_checkpoint:
+ /* The periodic log_checkpoint() call here makes it harder to
+ reproduce bugs in crash recovery or mariabackup --prepare, or
+ in code that writes the redo log records. Omitting the call
+ here should not affect correctness, because log_free_check()
+ should still be invoking checkpoints when needed. */
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", goto next;);
+
+ if (!recv_recovery_is_on() && srv_operation == SRV_OPERATION_NORMAL)
+ log_checkpoint();
+ }
+ }
+ else if (ulint n= page_cleaner_flush_pages_recommendation(last_pages,
+ oldest_lsn,
+ dirty_pct))
+ {
+ page_cleaner.flush_pass++;
+ const ulint tm= ut_time_ms();
+ last_pages= n_flushed= buf_flush_lists(n, LSN_MAX);
+ page_cleaner.flush_time+= ut_time_ms() - tm;
- buf_flush_wait_batch_end(false);
- buf_flush_wait_LRU_batch_end();
+ if (n_flushed)
+ {
+ MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_ADAPTIVE_TOTAL_PAGE,
+ MONITOR_FLUSH_ADAPTIVE_COUNT,
+ MONITOR_FLUSH_ADAPTIVE_PAGES,
+ n_flushed);
+ goto do_checkpoint;
+ }
+ }
- } while (!success || n_flushed > 0);
+#ifdef UNIV_DEBUG
+ while (innodb_page_cleaner_disabled_debug && !buf_flush_sync_lsn &&
+ srv_shutdown_state == SRV_SHUTDOWN_NONE)
+ os_thread_sleep(100000);
+#endif /* UNIV_DEBUG */
- /* Some sanity checks */
- ut_ad(!srv_any_background_activity());
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_FLUSH_PHASE);
- ut_a(UT_LIST_GET_LEN(buf_pool.flush_list) == 0);
+#ifndef DBUG_OFF
+next:
+#endif /* !DBUG_OFF */
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ }
- /* We have lived our life. Time to die. */
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
-thread_exit:
- page_cleaner.is_running = false;
- mutex_destroy(&page_cleaner.mutex);
+ if (srv_fast_shutdown != 2)
+ {
+ buf_flush_wait_batch_end_acquiring_mutex(true);
+ buf_flush_wait_batch_end_acquiring_mutex(false);
+ }
- os_event_destroy(page_cleaner.is_finished);
+ log_flush_task.wait();
- buf_page_cleaner_is_active = false;
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ lsn_limit= buf_flush_sync_lsn;
+ if (UNIV_UNLIKELY(lsn_limit != 0))
+ goto furious_flush;
+ buf_page_cleaner_is_active= false;
+ mysql_cond_broadcast(&buf_pool.done_flush_list);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
- my_thread_end();
- /* We count the number of threads in os_thread_exit(). A created
- thread should always use that to exit and not use return() to exit. */
- os_thread_exit();
+ my_thread_end();
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+ os_thread_exit();
- OS_THREAD_DUMMY_RETURN;
+ OS_THREAD_DUMMY_RETURN;
}
-static void pc_flush_slot_func(void*)
+/** Initialize page_cleaner. */
+ATTRIBUTE_COLD void buf_flush_page_cleaner_init()
{
- while (pc_flush_slot() > 0) {};
+ ut_ad(!buf_page_cleaner_is_active);
+ ut_ad(srv_operation == SRV_OPERATION_NORMAL ||
+ srv_operation == SRV_OPERATION_RESTORE ||
+ srv_operation == SRV_OPERATION_RESTORE_EXPORT);
+ buf_flush_sync_lsn= 0;
+ buf_page_cleaner_is_active= true;
+ os_thread_create(buf_flush_page_cleaner);
}
+/** @return the number of dirty pages in the buffer pool */
+static ulint buf_flush_list_length()
+{
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ const ulint len= UT_LIST_GET_LEN(buf_pool.flush_list);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ return len;
+}
-/** Initialize page_cleaner. */
-void buf_flush_page_cleaner_init()
+/** Flush the buffer pool on shutdown. */
+ATTRIBUTE_COLD void buf_flush_buffer_pool()
{
- ut_ad(!page_cleaner.is_running);
+ ut_ad(!buf_page_cleaner_is_active);
+ ut_ad(!buf_flush_sync_lsn);
- mutex_create(LATCH_ID_PAGE_CLEANER, &page_cleaner.mutex);
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "Waiting to flush the buffer pool");
- page_cleaner.is_finished = os_event_create("pc_is_finished");
+ while (buf_pool.n_flush_list || buf_flush_list_length())
+ {
+ buf_flush_lists(srv_max_io_capacity, LSN_MAX);
+ timespec abstime;
- page_cleaner.is_running = true;
+ if (buf_pool.n_flush_list)
+ {
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "Waiting to flush " ULINTPF " pages",
+ buf_flush_list_length());
+ set_timespec(abstime, INNODB_EXTEND_TIMEOUT_INTERVAL / 2);
+ mysql_mutex_lock(&buf_pool.mutex);
+ while (buf_pool.n_flush_list)
+ mysql_cond_timedwait(&buf_pool.done_flush_list, &buf_pool.mutex,
+ &abstime);
+ mysql_mutex_unlock(&buf_pool.mutex);
+ }
+ }
- buf_page_cleaner_is_active = true;
- os_thread_create(buf_flush_page_cleaner, NULL, NULL);
+ ut_ad(!buf_pool.any_io_pending());
+ log_flush_task.wait();
}
/** Synchronously flush dirty blocks.
NOTE: The calling thread is not allowed to hold any buffer page latches! */
void buf_flush_sync()
{
- bool success;
- do {
- success = buf_flush_lists(ULINT_MAX, LSN_MAX, NULL);
- buf_flush_wait_batch_end(false);
- } while (!success);
-}
-
-/** Request IO burst and wake page_cleaner up.
-@param[in] lsn_limit upper limit of LSN to be flushed */
-void buf_flush_request_force(lsn_t lsn_limit)
-{
- /* adjust based on lsn_avg_rate not to get old */
- lsn_t lsn_target = lsn_limit + lsn_avg_rate * 3;
-
- mutex_enter(&page_cleaner.mutex);
- if (lsn_target > buf_flush_sync_lsn) {
- buf_flush_sync_lsn = lsn_target;
- }
- mutex_exit(&page_cleaner.mutex);
+ ut_ad(!sync_check_iterate(dict_sync_check()));
- os_event_set(buf_flush_event);
+ for (;;)
+ {
+ const ulint n_flushed= buf_flush_lists(srv_max_io_capacity, LSN_MAX);
+ buf_flush_wait_batch_end_acquiring_mutex(false);
+ if (!n_flushed)
+ {
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ const auto len= UT_LIST_GET_LEN(buf_pool.flush_list);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
+ if (!len)
+ return;
+ }
+ }
}
#ifdef UNIV_DEBUG
@@ -2915,21 +2261,13 @@ struct Check {
static void buf_flush_validate_low()
{
buf_page_t* bpage;
- const ib_rbt_node_t* rnode = NULL;
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
+ mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
ut_list_validate(buf_pool.flush_list, Check());
bpage = UT_LIST_GET_FIRST(buf_pool.flush_list);
- /* If we are in recovery mode i.e.: flush_rbt != NULL
- then each block in the flush_list must also be present
- in the flush_rbt. */
- if (UNIV_LIKELY_NULL(buf_pool.flush_rbt)) {
- rnode = rbt_first(buf_pool.flush_rbt);
- }
-
while (bpage != NULL) {
const lsn_t om = bpage->oldest_modification();
/* A page in buf_pool.flush_list can be in
@@ -2938,36 +2276,22 @@ static void buf_flush_validate_low()
original descriptor can have this state and still be
in the flush list waiting to acquire the
buf_pool.flush_list_mutex to complete the relocation. */
- ut_a(bpage->in_file()
- || bpage->state() == BUF_BLOCK_REMOVE_HASH);
- ut_a(om > 0);
-
- if (UNIV_LIKELY_NULL(buf_pool.flush_rbt)) {
- buf_page_t** prpage;
-
- ut_a(rnode != NULL);
- prpage = rbt_value(buf_page_t*, rnode);
-
- ut_a(*prpage != NULL);
- ut_a(*prpage == bpage);
- rnode = rbt_next(buf_pool.flush_rbt, rnode);
- }
+ ut_d(const auto s= bpage->state());
+ ut_ad(s == BUF_BLOCK_ZIP_PAGE || s == BUF_BLOCK_FILE_PAGE
+ || s == BUF_BLOCK_REMOVE_HASH);
+ ut_ad(om > 0);
bpage = UT_LIST_GET_NEXT(list, bpage);
-
- ut_a(!bpage || om >= bpage->oldest_modification());
+ ut_ad(!bpage || recv_recovery_is_on()
+ || om >= bpage->oldest_modification());
}
-
- /* By this time we must have exhausted the traversal of
- flush_rbt (if active) as well. */
- ut_a(rnode == NULL);
}
/** Validate the flush list. */
void buf_flush_validate()
{
- mutex_enter(&buf_pool.flush_list_mutex);
- buf_flush_validate_low();
- mutex_exit(&buf_pool.flush_list_mutex);
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ buf_flush_validate_low();
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 26c5850d290..f9ed938b20c 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -25,26 +25,23 @@ Created 11/5/1995 Heikki Tuuri
*******************************************************/
#include "buf0lru.h"
-#include "ut0byte.h"
-#include "ut0rnd.h"
#include "sync0rw.h"
-#include "hash0hash.h"
-#include "os0event.h"
#include "fil0fil.h"
#include "btr0btr.h"
#include "buf0buddy.h"
#include "buf0buf.h"
-#include "buf0dblwr.h"
#include "buf0flu.h"
#include "buf0rea.h"
#include "btr0sea.h"
-#include "ibuf0ibuf.h"
#include "os0file.h"
#include "page0zip.h"
#include "log0recv.h"
#include "srv0srv.h"
#include "srv0mon.h"
+/** Flush this many pages in buf_LRU_get_free_block() */
+size_t innodb_lru_flush_size;
+
/** The number of blocks from the LRU_old pointer onward, including
the block pointed to, must be buf_pool.LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
of the whole LRU list length, except that the tolerance defined below
@@ -52,28 +49,13 @@ is allowed. Note that the tolerance must be small enough such that for
even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
allowed to point to either end of the LRU list. */
-static const ulint BUF_LRU_OLD_TOLERANCE = 20;
+static constexpr ulint BUF_LRU_OLD_TOLERANCE = 20;
/** The minimum amount of non-old blocks when the LRU_old list exists
(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
@see buf_LRU_old_adjust_len */
#define BUF_LRU_NON_OLD_MIN_LEN 5
-#ifdef BTR_CUR_HASH_ADAPT
-/** When dropping the search hash index entries before deleting an ibd
-file, we build a local array of pages belonging to that tablespace
-in the buffer pool. Following is the size of that array.
-We also release buf_pool.mutex after scanning this many pages of the
-flush_list when dropping a table. This is to ensure that other threads
-are not blocked for extended period of time when using very large
-buffer pools. */
-static const ulint BUF_LRU_DROP_SEARCH_SIZE = 1024;
-#endif /* BTR_CUR_HASH_ADAPT */
-
-/** We scan these many blocks when looking for a clean page to evict
-during LRU eviction. */
-static const ulint BUF_LRU_SEARCH_SCAN_THRESHOLD = 100;
-
/** If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */
static bool buf_lru_switched_on_innodb_mon = false;
@@ -155,7 +137,7 @@ static void buf_LRU_block_free_hashed_page(buf_block_t *block)
static inline void incr_LRU_size_in_bytes(const buf_page_t* bpage)
{
/* FIXME: use atomics, not mutex */
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
buf_pool.stat.LRU_bytes += bpage->physical_size();
@@ -166,7 +148,7 @@ static inline void incr_LRU_size_in_bytes(const buf_page_t* bpage)
instead of the general LRU list */
bool buf_LRU_evict_from_unzip_LRU()
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
/* If the unzip_LRU list is empty, we can only use the LRU. */
if (UT_LIST_GET_LEN(buf_pool.unzip_LRU) == 0) {
@@ -202,314 +184,19 @@ bool buf_LRU_evict_from_unzip_LRU()
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
}
-#ifdef BTR_CUR_HASH_ADAPT
-/**
-While flushing (or removing dirty) pages from a tablespace we don't
-want to hog the CPU and resources. Release the buffer pool and block
-mutex and try to force a context switch. Then reacquire the same mutexes.
-The current page is "fixed" before the release of the mutexes and then
-"unfixed" again once we have reacquired the mutexes.
-@param[in,out] bpage current page */
-static void buf_flush_yield(buf_page_t *bpage)
-{
- mutex_exit(&buf_pool.flush_list_mutex);
- ut_ad(bpage->oldest_modification());
- ut_ad(bpage->in_file());
- ut_ad(bpage->io_fix() == BUF_IO_NONE);
- /** Make the block sticky, so that even after we release buf_pool.mutex:
- (1) it cannot be removed from the buf_pool.flush_list
- (2) bpage cannot be relocated in buf_pool
- (3) bpage->in_LRU_list cannot change
- However, bpage->LRU can change. */
- bpage->set_io_fix(BUF_IO_PIN);
- mutex_exit(&buf_pool.mutex);
-
- /* Try and force a context switch. */
- os_thread_yield();
-
- mutex_enter(&buf_pool.mutex);
- bpage->io_unfix();
- mutex_enter(&buf_pool.flush_list_mutex);
- /* Should not have been removed from the flush
- list during the yield. However, this check is
- not sufficient to catch a remove -> add. */
- ut_ad(bpage->oldest_modification());
-}
-
-/******************************************************************//**
-If we have hogged the resources for too long then release the buffer
-pool and flush list mutex and do a thread yield. Set the current page
-to "sticky" so that it is not relocated during the yield.
-@return true if yielded */
-static MY_ATTRIBUTE((warn_unused_result))
-bool
-buf_flush_try_yield(
-/*================*/
- buf_page_t* bpage, /*!< in/out: bpage to remove */
- ulint processed) /*!< in: number of pages processed */
-{
- /* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
- loop we release buf_pool.mutex to let other threads
- do their job but only if the block is not IO fixed. This
- ensures that the block stays in its position in the
- flush_list. */
-
- if (bpage != NULL
- && processed >= BUF_LRU_DROP_SEARCH_SIZE
- && bpage->io_fix() == BUF_IO_NONE) {
-
- /* Release the buf_pool.mutex
- to give the other threads a go. */
-
- buf_flush_yield(bpage);
- return(true);
- }
-
- return(false);
-}
-#endif /* BTR_CUR_HASH_ADAPT */
-
-/** Remove a single page from flush_list.
-@param[in,out] bpage buffer page to remove
-@param[in] flush whether to flush the page before removing
-@return true if page was removed. */
-static bool buf_flush_or_remove_page(buf_page_t *bpage, bool flush)
-{
- ut_ad(mutex_own(&buf_pool.mutex));
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
-
- /* bpage->id and bpage->io_fix are protected by
- buf_pool.mutex (and bpage->id additionally by hash_lock).
- It is safe to check them while holding buf_pool.mutex only. */
-
- if (bpage->io_fix() != BUF_IO_NONE) {
-
- /* We cannot remove this page during this scan
- yet; maybe the system is currently reading it
- in, or flushing the modifications to the file */
- return(false);
-
- }
-
- bool processed = false;
-
- /* We have to release the flush_list_mutex to obey the
- latching order. We are however guaranteed that the page
- will stay in the flush_list and won't be relocated because
- buf_flush_remove() and buf_flush_relocate_on_flush_list()
- need buf_pool.mutex as well. */
-
- mutex_exit(&buf_pool.flush_list_mutex);
-
- ut_ad(bpage->oldest_modification());
-
- if (!flush) {
- buf_flush_remove(bpage);
- processed = true;
- } else if (bpage->ready_for_flush()) {
- processed = buf_flush_page(bpage, IORequest::SINGLE_PAGE,
- nullptr, false);
-
- if (processed) {
- mutex_enter(&buf_pool.mutex);
- }
- }
-
- mutex_enter(&buf_pool.flush_list_mutex);
-
- ut_ad(mutex_own(&buf_pool.mutex));
-
- return(processed);
-}
-
-/** Remove all dirty pages belonging to a given tablespace when we are
-deleting the data file of that tablespace.
-The pages still remain a part of LRU and are evicted from
-the list as they age towards the tail of the LRU.
-@param[in] id tablespace identifier
-@param[in] flush whether to flush the pages before removing
-@param[in] first first page to be flushed or evicted
-@return whether all matching dirty pages were removed */
-static bool buf_flush_or_remove_pages(ulint id, bool flush, ulint first)
-{
- buf_page_t* prev;
- buf_page_t* bpage;
- ulint processed = 0;
-
- mutex_enter(&buf_pool.flush_list_mutex);
-rescan:
- bool all_freed = true;
-
- for (bpage = UT_LIST_GET_LAST(buf_pool.flush_list);
- bpage != NULL;
- bpage = prev) {
-
- ut_a(bpage->in_file());
-
- /* Save the previous link because once we free the
- page we can't rely on the links. */
-
- prev = UT_LIST_GET_PREV(list, bpage);
-
- const page_id_t bpage_id(bpage->id());
-
- if (id != bpage_id.space()) {
- /* Skip this block, because it is for a
- different tablespace. */
- } else if (bpage_id.page_no() < first) {
- /* Skip this block, because it is below the limit. */
- } else if (!buf_flush_or_remove_page(bpage, flush)) {
-
- /* Remove was unsuccessful, we have to try again
- by scanning the entire list from the end.
- This also means that we never released the
- buf_pool mutex. Therefore we can trust the prev
- pointer.
- buf_flush_or_remove_page() released the
- flush list mutex but not the buf_pool mutex.
- Therefore it is possible that a new page was
- added to the flush list. For example, in case
- where we are at the head of the flush list and
- prev == NULL. That is OK because we have the
- tablespace quiesced and no new pages for this
- space-id should enter flush_list. This is
- because the only callers of this function are
- DROP TABLE and FLUSH TABLE FOR EXPORT.
- We know that we'll have to do at least one more
- scan but we don't break out of loop here and
- try to do as much work as we can in this
- iteration. */
-
- all_freed = false;
- } else if (flush) {
-
- /* The processing was successful. And during the
- processing we have released the buf_pool mutex
- when calling buf_page_flush(). We cannot trust
- prev pointer. */
- goto rescan;
- }
-
-#ifdef BTR_CUR_HASH_ADAPT
- ++processed;
-
- /* Yield if we have hogged the CPU and mutexes for too long. */
- if (buf_flush_try_yield(prev, processed)) {
- /* Reset the batch size counter if we had to yield. */
- processed = 0;
- }
-#endif /* BTR_CUR_HASH_ADAPT */
- }
-
- mutex_exit(&buf_pool.flush_list_mutex);
-
- return(all_freed);
-}
-
-/** Remove or flush all the dirty pages that belong to a given tablespace.
-The pages will remain in the LRU list and will be evicted from the LRU list
-as they age and move towards the tail of the LRU list.
-@param[in] id tablespace identifier
-@param[in] flush whether to flush the pages before removing
-@param[in] first first page to be flushed or evicted */
-static void buf_flush_dirty_pages(ulint id, bool flush, ulint first)
-{
- mutex_enter(&buf_pool.mutex);
- while (!buf_flush_or_remove_pages(id, flush, first))
- {
- mutex_exit(&buf_pool.mutex);
- ut_d(buf_flush_validate());
- os_thread_sleep(2000);
- mutex_enter(&buf_pool.mutex);
- }
-
-#ifdef UNIV_DEBUG
- if (!first)
- {
- mutex_enter(&buf_pool.flush_list_mutex);
-
- for (buf_page_t *bpage= UT_LIST_GET_FIRST(buf_pool.flush_list); bpage;
- bpage= UT_LIST_GET_NEXT(list, bpage))
- {
- ut_ad(bpage->in_file());
- ut_ad(bpage->oldest_modification());
- ut_ad(id != bpage->id().space());
- }
-
- mutex_exit(&buf_pool.flush_list_mutex);
- }
-#endif
-
- mutex_exit(&buf_pool.mutex);
-}
-
-/** Empty the flush list for all pages belonging to a tablespace.
-@param[in] id tablespace identifier
-@param[in] flush whether to write the pages to files
-@param[in] first first page to be flushed or evicted */
-void buf_LRU_flush_or_remove_pages(ulint id, bool flush, ulint first)
-{
- /* Pages in the system tablespace must never be discarded. */
- ut_ad(id || flush);
-
- buf_flush_dirty_pages(id, flush, first);
-
- if (flush) {
- /* Ensure that all asynchronous IO is completed. */
- os_aio_wait_until_no_pending_writes();
- fil_flush(id);
- }
-}
-
-#ifdef UNIV_DEBUG
-/********************************************************************//**
-Insert a compressed block into buf_pool.zip_clean in the LRU order. */
-void
-buf_LRU_insert_zip_clean(
-/*=====================*/
- buf_page_t* bpage) /*!< in: pointer to the block in question */
-{
- ut_ad(mutex_own(&buf_pool.mutex));
- ut_ad(bpage->state() == BUF_BLOCK_ZIP_PAGE);
- ut_ad(!bpage->oldest_modification());
-
- /* Find the first successor of bpage in the LRU list
- that is in the zip_clean list. */
- buf_page_t* b = bpage;
-
- do {
- b = UT_LIST_GET_NEXT(LRU, b);
- } while (b && (b->state() != BUF_BLOCK_ZIP_PAGE
- || b->oldest_modification()));
-
- /* Insert bpage before b, i.e., after the predecessor of b. */
- if (b != NULL) {
- b = UT_LIST_GET_PREV(list, b);
- }
-
- if (b != NULL) {
- UT_LIST_INSERT_AFTER(buf_pool.zip_clean, b, bpage);
- } else {
- UT_LIST_ADD_FIRST(buf_pool.zip_clean, bpage);
- }
-}
-#endif /* UNIV_DEBUG */
-
/** Try to free an uncompressed page of a compressed block from the unzip
LRU list. The compressed page is preserved, and it need not be clean.
-@param[in] scan_all true=scan the whole list;
- false=scan srv_LRU_scan_depth / 2 blocks
+@param limit maximum number of blocks to scan
@return true if freed */
-static bool buf_LRU_free_from_unzip_LRU_list(bool scan_all)
+static bool buf_LRU_free_from_unzip_LRU_list(ulint limit)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
if (!buf_LRU_evict_from_unzip_LRU()) {
return(false);
}
ulint scanned = 0;
- const ulint limit = scan_all ? ULINT_UNDEFINED : srv_LRU_scan_depth;
bool freed = false;
for (buf_block_t* block = UT_LIST_GET_LAST(buf_pool.unzip_LRU);
@@ -540,31 +227,24 @@ static bool buf_LRU_free_from_unzip_LRU_list(bool scan_all)
}
/** Try to free a clean page from the common LRU list.
-@param[in] scan_all true=scan the whole LRU list
- false=use BUF_LRU_SEARCH_SCAN_THRESHOLD
+@param limit maximum number of blocks to scan
@return whether a page was freed */
-static bool buf_LRU_free_from_common_LRU_list(bool scan_all)
+static bool buf_LRU_free_from_common_LRU_list(ulint limit)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ulint scanned = 0;
bool freed = false;
for (buf_page_t* bpage = buf_pool.lru_scan_itr.start();
- bpage && (scan_all || scanned < BUF_LRU_SEARCH_SCAN_THRESHOLD);
+ bpage && scanned < limit;
++scanned, bpage = buf_pool.lru_scan_itr.get()) {
buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
buf_pool.lru_scan_itr.set(prev);
const auto accessed = bpage->is_accessed();
- freed = bpage->ready_for_replace();
-
- if (freed) {
- freed = buf_LRU_free_page(bpage, true);
- if (!freed) {
- continue;
- }
-
+ if (!bpage->oldest_modification()
+ && buf_LRU_free_page(bpage, true)) {
if (!accessed) {
/* Keep track of pages that are evicted without
ever being accessed. This gives us a measure of
@@ -572,6 +252,7 @@ static bool buf_LRU_free_from_common_LRU_list(bool scan_all)
++buf_pool.stat.n_ra_pages_evicted;
}
+ freed = true;
break;
}
}
@@ -588,15 +269,14 @@ static bool buf_LRU_free_from_common_LRU_list(bool scan_all)
}
/** Try to free a replaceable block.
-@param[in] scan_all true=scan the whole LRU list,
- false=use BUF_LRU_SEARCH_SCAN_THRESHOLD
+@param limit maximum number of blocks to scan
@return true if found and freed */
-bool buf_LRU_scan_and_free_block(bool scan_all)
+bool buf_LRU_scan_and_free_block(ulint limit)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
- return(buf_LRU_free_from_unzip_LRU_list(scan_all)
- || buf_LRU_free_from_common_LRU_list(scan_all));
+ return buf_LRU_free_from_unzip_LRU_list(limit) ||
+ buf_LRU_free_from_common_LRU_list(limit);
}
/** @return a buffer block from the buf_pool.free list
@@ -605,7 +285,7 @@ buf_block_t* buf_LRU_get_free_only()
{
buf_block_t* block;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
block = reinterpret_cast<buf_block_t*>(
UT_LIST_GET_FIRST(buf_pool.free));
@@ -651,106 +331,89 @@ function will either assert or issue a warning and switch on the
status monitor. */
static void buf_LRU_check_size_of_non_data_objects()
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
- if (!recv_recovery_is_on()
- && buf_pool.curr_size == buf_pool.old_size
- && UT_LIST_GET_LEN(buf_pool.free)
- + UT_LIST_GET_LEN(buf_pool.LRU) < buf_pool.curr_size / 20) {
+ if (recv_recovery_is_on() || buf_pool.curr_size != buf_pool.old_size)
+ return;
- ib::fatal() << "Over 95 percent of the buffer pool is"
- " occupied by lock heaps"
+ const auto s= UT_LIST_GET_LEN(buf_pool.free) + UT_LIST_GET_LEN(buf_pool.LRU);
+
+ if (s < buf_pool.curr_size / 20)
+ ib::fatal() << "Over 95 percent of the buffer pool is"
+ " occupied by lock heaps"
#ifdef BTR_CUR_HASH_ADAPT
- " or the adaptive hash index!"
+ " or the adaptive hash index"
#endif /* BTR_CUR_HASH_ADAPT */
- " Check that your transactions do not set too many"
- " row locks, or review if"
- " innodb_buffer_pool_size="
- << (buf_pool.curr_size >> (20U - srv_page_size_shift))
- << "M could be bigger.";
- } else if (!recv_recovery_is_on()
- && buf_pool.curr_size == buf_pool.old_size
- && (UT_LIST_GET_LEN(buf_pool.free)
- + UT_LIST_GET_LEN(buf_pool.LRU))
- < buf_pool.curr_size / 3) {
-
- if (!buf_lru_switched_on_innodb_mon && srv_monitor_timer) {
-
- /* Over 67 % of the buffer pool is occupied by lock
- heaps or the adaptive hash index. This may be a memory
- leak! */
-
- ib::warn() << "Over 67 percent of the buffer pool is"
- " occupied by lock heaps"
+ "! Check that your transactions do not set too many"
+ " row locks, or review if innodb_buffer_pool_size="
+ << (buf_pool.curr_size >> (20U - srv_page_size_shift))
+ << "M could be bigger.";
+
+ if (s < buf_pool.curr_size / 3)
+ {
+ if (!buf_lru_switched_on_innodb_mon && srv_monitor_timer)
+ {
+ /* Over 67 % of the buffer pool is occupied by lock heaps or
+ the adaptive hash index. This may be a memory leak! */
+ ib::warn() << "Over 67 percent of the buffer pool is"
+ " occupied by lock heaps"
#ifdef BTR_CUR_HASH_ADAPT
- " or the adaptive hash index!"
+ " or the adaptive hash index"
#endif /* BTR_CUR_HASH_ADAPT */
- " Check that your transactions do not"
- " set too many row locks."
- " innodb_buffer_pool_size="
- << (buf_pool.curr_size >>
- (20U - srv_page_size_shift)) << "M."
- " Starting the InnoDB Monitor to print"
- " diagnostics.";
-
- buf_lru_switched_on_innodb_mon = true;
- srv_print_innodb_monitor = TRUE;
- srv_monitor_timer_schedule_now();
- }
-
- } else if (buf_lru_switched_on_innodb_mon) {
-
- /* Switch off the InnoDB Monitor; this is a simple way
- to stop the monitor if the situation becomes less urgent,
- but may also surprise users if the user also switched on the
- monitor! */
-
- buf_lru_switched_on_innodb_mon = false;
- srv_print_innodb_monitor = FALSE;
- }
+ "! Check that your transactions do not set too many row locks."
+ " innodb_buffer_pool_size="
+ << (buf_pool.curr_size >> (20U - srv_page_size_shift))
+ << "M. Starting the InnoDB Monitor to print diagnostics.";
+ buf_lru_switched_on_innodb_mon= true;
+ srv_print_innodb_monitor= TRUE;
+ srv_monitor_timer_schedule_now();
+ }
+ }
+ else if (buf_lru_switched_on_innodb_mon)
+ {
+ /* Switch off the InnoDB Monitor; this is a simple way to stop the
+ monitor if the situation becomes less urgent, but may also
+ surprise users who did SET GLOBAL innodb_status_output=ON earlier! */
+ buf_lru_switched_on_innodb_mon= false;
+ srv_print_innodb_monitor= FALSE;
+ }
}
-/** Get a free block from the buf_pool. The block is taken off the
-free list. If free list is empty, blocks are moved from the end of the
-LRU list to the free list.
+/** Get a block from the buf_pool.free list.
+If the list is empty, blocks will be moved from the end of buf_pool.LRU
+to buf_pool.free.
This function is called from a user thread when it needs a clean
block to read in a page. Note that we only ever get a block from
the free list. Even when we flush a page or find a page in LRU scan
we put it to free list to be used.
* iteration 0:
- * get a block from free list, success:done
+ * get a block from the buf_pool.free list, success:done
* if buf_pool.try_LRU_scan is set
- * scan LRU up to srv_LRU_scan_depth to find a clean block
- * the above will put the block on free list
+ * scan LRU up to 100 pages to free a clean block
* success:retry the free list
- * flush one dirty page from tail of LRU to disk
- * the above will put the block on free list
+ * flush up to innodb_lru_flush_size LRU blocks to data files
+ (until UT_LIST_GET_GEN(buf_pool.free) < innodb_lru_scan_depth)
+ * on buf_page_write_complete() the blocks will put on buf_pool.free list
* success: retry the free list
-* iteration 1:
- * same as iteration 0 except:
- * scan whole LRU list
- * scan LRU list even if buf_pool.try_LRU_scan is not set
-* iteration > 1:
- * same as iteration 1 but sleep 10ms
+* subsequent iterations: same as iteration 0 except:
+ * scan whole LRU list
+ * scan LRU list even if buf_pool.try_LRU_scan is not set
@param have_mutex whether buf_pool.mutex is already being held
@return the free control block, in state BUF_BLOCK_MEMORY */
buf_block_t* buf_LRU_get_free_block(bool have_mutex)
{
- buf_block_t* block = NULL;
- bool freed = false;
ulint n_iterations = 0;
ulint flush_failures = 0;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
if (have_mutex) {
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
goto got_mutex;
}
loop:
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
got_mutex:
-
buf_LRU_check_size_of_non_data_objects();
DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
@@ -758,49 +421,38 @@ got_mutex:
n_iterations = 21;
goto not_found;});
+retry:
/* If there is a block in the free list, take it */
- block = buf_LRU_get_free_only();
-
- if (block) {
+ if (buf_block_t* block = buf_LRU_get_free_only()) {
if (!have_mutex) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
memset(&block->page.zip, 0, sizeof block->page.zip);
- return(block);
+ return block;
}
MONITOR_INC( MONITOR_LRU_GET_FREE_LOOPS );
- freed = false;
if (n_iterations || buf_pool.try_LRU_scan) {
/* If no block was in the free list, search from the
end of the LRU list and try to free a block there.
If we are doing for the first time we'll scan only
tail of the LRU list otherwise we scan the whole LRU
list. */
- freed = buf_LRU_scan_and_free_block(n_iterations > 0);
-
- if (!freed && n_iterations == 0) {
- /* Tell other threads that there is no point
- in scanning the LRU list. This flag is set to
- TRUE again when we flush a batch from this
- buffer pool. */
- buf_pool.try_LRU_scan = false;
-
- /* Also tell the page_cleaner thread that
- there is work for it to do. */
- os_event_set(buf_flush_event);
+ if (buf_LRU_scan_and_free_block(n_iterations
+ ? ULINT_UNDEFINED : 100)) {
+ goto retry;
}
+
+ /* Tell other threads that there is no point
+ in scanning the LRU list. */
+ buf_pool.try_LRU_scan = false;
}
#ifndef DBUG_OFF
not_found:
#endif
-
- mutex_exit(&buf_pool.mutex);
-
- if (freed) {
- goto loop;
- }
+ mysql_mutex_unlock(&buf_pool.mutex);
+ buf_flush_wait_batch_end_acquiring_mutex(true);
if (n_iterations > 20 && !buf_lru_free_blocks_error_printed
&& srv_buf_pool_old_size == srv_buf_pool_size) {
@@ -822,18 +474,8 @@ not_found:
buf_lru_free_blocks_error_printed = true;
}
- /* If we have scanned the whole LRU and still are unable to
- find a free block then we should sleep here to let the
- page_cleaner do an LRU batch for us. */
-
- if (!srv_read_only_mode) {
- os_event_set(buf_flush_event);
- }
-
if (n_iterations > 1) {
-
MONITOR_INC( MONITOR_LRU_GET_FREE_WAITS );
- os_thread_sleep(10000);
}
/* No free block was found: try to flush the LRU list.
@@ -844,10 +486,10 @@ not_found:
TODO: A more elegant way would have been to return the freed
up block to the caller here but the code that deals with
removing the block from page_hash and LRU_list is fairly
- involved (particularly in case of compressed pages). We
+ involved (particularly in case of ROW_FORMAT=COMPRESSED pages). We
can do that in a separate patch sometime in future. */
- if (!buf_flush_single_page_from_LRU()) {
+ if (!buf_flush_lists(innodb_lru_flush_size, 0)) {
MONITOR_INC(MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT);
++flush_failures;
}
@@ -867,7 +509,7 @@ static void buf_LRU_old_adjust_len()
ulint new_len;
ut_a(buf_pool.LRU_old);
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(buf_pool.LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
ut_ad(buf_pool.LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
compile_time_assert(BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN
@@ -928,7 +570,7 @@ static void buf_LRU_old_adjust_len()
called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */
static void buf_LRU_old_init()
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_a(UT_LIST_GET_LEN(buf_pool.LRU) == BUF_LRU_OLD_MIN_LEN);
/* We first initialize all blocks in the LRU list as old and then use
@@ -957,7 +599,7 @@ static void buf_LRU_old_init()
static void buf_unzip_LRU_remove_block_if_needed(buf_page_t* bpage)
{
ut_ad(bpage->in_file());
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
if (bpage->belongs_to_unzip_LRU()) {
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
@@ -1040,7 +682,7 @@ buf_unzip_LRU_add_block(
ibool old) /*!< in: TRUE if should be put to the end
of the list, else put to the start */
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_a(block->page.belongs_to_unzip_LRU());
ut_ad(!block->in_unzip_LRU_list);
ut_d(block->in_unzip_LRU_list = true);
@@ -1064,7 +706,7 @@ buf_LRU_add_block(
LRU list is very short, the block is added to
the start, regardless of this parameter */
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(!bpage->in_LRU_list);
if (!old || (UT_LIST_GET_LEN(buf_pool.LRU) < BUF_LRU_OLD_MIN_LEN)) {
@@ -1124,7 +766,7 @@ void buf_page_make_young(buf_page_t *bpage)
{
ut_ad(bpage->in_file());
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (UNIV_UNLIKELY(bpage->old))
buf_pool.stat.n_pages_made_young++;
@@ -1132,7 +774,7 @@ void buf_page_make_young(buf_page_t *bpage)
buf_LRU_remove_block(bpage);
buf_LRU_add_block(bpage, false);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/** Try to free a block. If bpage is a descriptor of a compressed-only
@@ -1147,7 +789,7 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
const page_id_t id(bpage->id());
buf_page_t* b = nullptr;
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(bpage->in_file());
ut_ad(bpage->in_LRU_list);
@@ -1188,7 +830,7 @@ func_exit:
b->set_state(BUF_BLOCK_ZIP_PAGE);
}
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(bpage->in_file());
ut_ad(bpage->in_LRU_list);
@@ -1278,14 +920,7 @@ func_exit:
buf_LRU_add_block(b, b->old);
}
- if (!b->oldest_modification()) {
-#ifdef UNIV_DEBUG
- buf_LRU_insert_zip_clean(b);
-#endif /* UNIV_DEBUG */
- } else {
- /* Relocate on buf_pool.flush_list. */
- buf_flush_relocate_on_flush_list(bpage, b);
- }
+ buf_flush_relocate_on_flush_list(bpage, b);
bpage->zip.data = nullptr;
@@ -1298,25 +933,35 @@ func_exit:
hash_lock->write_unlock();
}
- mutex_exit(&buf_pool.mutex);
-
- /* Remove possible adaptive hash index on the page.
- The page was declared uninitialized by
- buf_LRU_block_remove_hashed(). We need to flag
- the contents of the page valid (which it still is) in
- order to avoid bogus Valgrind or MSAN warnings.*/
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
- MEM_MAKE_DEFINED(block->frame, srv_page_size);
- btr_search_drop_page_hash_index(block);
- MEM_UNDEFINED(block->frame, srv_page_size);
+#ifdef BTR_CUR_HASH_ADAPT
+ if (block->index) {
+ mysql_mutex_unlock(&buf_pool.mutex);
+
+ /* Remove the adaptive hash index on the page.
+ The page was declared uninitialized by
+ buf_LRU_block_remove_hashed(). We need to flag
+ the contents of the page valid (which it still is) in
+ order to avoid bogus Valgrind or MSAN warnings.*/
+
+ MEM_MAKE_DEFINED(block->frame, srv_page_size);
+ btr_search_drop_page_hash_index(block);
+ MEM_UNDEFINED(block->frame, srv_page_size);
+
+ if (UNIV_LIKELY_NULL(b)) {
+ ut_ad(b->zip_size());
+ b->io_unfix();
+ }
+ mysql_mutex_lock(&buf_pool.mutex);
+ } else
+#endif
if (UNIV_LIKELY_NULL(b)) {
ut_ad(b->zip_size());
b->io_unfix();
}
- mutex_enter(&buf_pool.mutex);
buf_LRU_block_free_hashed_page(block);
return(true);
@@ -1377,6 +1022,16 @@ buf_LRU_block_free_non_file_page(
MEM_NOACCESS(block->frame, srv_page_size);
}
+/** Release a memory block to the buffer pool. */
+ATTRIBUTE_COLD void buf_pool_t::free_block(buf_block_t *block)
+{
+ ut_ad(this == &buf_pool);
+ mysql_mutex_lock(&mutex);
+ buf_LRU_block_free_non_file_page(block);
+ mysql_mutex_unlock(&mutex);
+}
+
+
/** Remove bpage from buf_pool.LRU and buf_pool.page_hash.
If bpage->state() == BUF_BLOCK_ZIP_PAGE && !bpage->oldest_modification(),
@@ -1395,7 +1050,7 @@ this case the block is already returned to the buddy allocator. */
static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
page_hash_latch *hash_lock, bool zip)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(hash_lock->is_write_locked());
ut_a(bpage->io_fix() == BUF_IO_NONE);
@@ -1486,9 +1141,6 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
ut_a(bpage->zip.ssize);
ut_ad(!bpage->oldest_modification());
-#ifdef UNIV_DEBUG
- UT_LIST_REMOVE(buf_pool.zip_clean, bpage);
-#endif /* UNIV_DEBUG */
hash_lock->write_unlock();
buf_pool_mutex_exit_forbid();
@@ -1593,7 +1245,7 @@ uint buf_LRU_old_ratio_update(uint old_pct, bool adjust)
}
if (adjust) {
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (ratio != buf_pool.LRU_old_ratio) {
buf_pool.LRU_old_ratio = ratio;
@@ -1604,7 +1256,7 @@ uint buf_LRU_old_ratio_update(uint old_pct, bool adjust)
}
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
} else {
buf_pool.LRU_old_ratio = ratio;
}
@@ -1657,7 +1309,7 @@ void buf_LRU_validate()
ulint old_len;
ulint new_len;
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (UT_LIST_GET_LEN(buf_pool.LRU) >= BUF_LRU_OLD_MIN_LEN) {
@@ -1735,7 +1387,7 @@ void buf_LRU_validate()
ut_a(block->page.belongs_to_unzip_LRU());
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
#endif /* UNIV_DEBUG */
@@ -1743,7 +1395,7 @@ void buf_LRU_validate()
/** Dump the LRU list to stderr. */
void buf_LRU_print()
{
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
for (buf_page_t* bpage = UT_LIST_GET_FIRST(buf_pool.LRU);
bpage != NULL;
@@ -1792,6 +1444,6 @@ void buf_LRU_print()
}
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG */
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index ed36873837e..2f59f1ae4d5 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -121,7 +121,7 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
const ulint fold= page_id.fold();
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
/* We must acquire hash_lock this early to prevent
a race condition with buf_pool_t::watch_remove() */
@@ -237,16 +237,13 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
/* The block must be put to the LRU list, to the old blocks.
The zip size is already set into the page zip */
buf_LRU_add_block(bpage, true/* to old blocks */);
-#ifdef UNIV_DEBUG
- buf_LRU_insert_zip_clean(bpage);
-#endif /* UNIV_DEBUG */
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
buf_pool.n_pend_reads++;
goto func_exit_no_mutex;
func_exit:
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
func_exit_no_mutex:
if (mode == BUF_READ_IBUF_PAGES_ONLY)
ibuf_mtr_commit(&mtr);
@@ -264,46 +261,48 @@ flag is cleared and the x-lock released by an i/o-handler thread.
@param[out] err DB_SUCCESS or DB_TABLESPACE_DELETED
if we are trying
to read from a non-existent tablespace
+@param[in,out] space tablespace
@param[in] sync true if synchronous aio is desired
@param[in] mode BUF_READ_IBUF_PAGES_ONLY, ...,
@param[in] page_id page id
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] unzip true=request uncompressed page
-@param[in] ignore whether to ignore out-of-bounds page_id
-@return 1 if a read request was queued, 0 if the page already resided
-in buf_pool, or if the page is in the doublewrite buffer blocks in
-which case it is never read into the pool, or if the tablespace does
-not exist or is being dropped */
+@return whether a read request was queued */
static
-ulint
+bool
buf_read_page_low(
dberr_t* err,
+ fil_space_t* space,
bool sync,
ulint mode,
const page_id_t page_id,
ulint zip_size,
- bool unzip,
- bool ignore = false)
+ bool unzip)
{
buf_page_t* bpage;
*err = DB_SUCCESS;
- if (!page_id.space() && buf_dblwr_page_inside(page_id.page_no())) {
-
+ if (buf_dblwr.is_inside(page_id)) {
ib::error() << "Trying to read doublewrite buffer page "
<< page_id;
- return(0);
+ ut_ad(0);
+nothing_read:
+ space->release();
+ return false;
}
- if (ibuf_bitmap_page(page_id, zip_size) || trx_sys_hdr_page(page_id)) {
+ if (sync) {
+ } else if (trx_sys_hdr_page(page_id)
+ || ibuf_bitmap_page(page_id, zip_size)
+ || (!recv_no_ibuf_operations
+ && ibuf_page(page_id, zip_size, nullptr))) {
/* Trx sys header is so low in the latching order that we play
safe and do not leave the i/o-completion to an asynchronous
- i/o-thread. Ibuf bitmap pages must always be read with
+ i/o-thread. Change buffer pages must always be read with
syncronous i/o, to make sure they do not get involved in
thread deadlocks. */
-
sync = true;
}
@@ -314,20 +313,19 @@ buf_read_page_low(
bpage = buf_page_init_for_read(mode, page_id, zip_size, unzip);
if (bpage == NULL) {
-
- return(0);
+ goto nothing_read;
}
- DBUG_LOG("ib_buf",
- "read page " << page_id << " zip_size=" << zip_size
- << " unzip=" << unzip << ',' << (sync ? "sync" : "async"));
-
ut_ad(bpage->in_file());
if (sync) {
- thd_wait_begin(NULL, THD_WAIT_DISKIO);
+ thd_wait_begin(nullptr, THD_WAIT_DISKIO);
}
+ DBUG_LOG("ib_buf",
+ "read page " << page_id << " zip_size=" << zip_size
+ << " unzip=" << unzip << ',' << (sync ? "sync" : "async"));
+
void* dst;
if (zip_size) {
@@ -338,20 +336,18 @@ buf_read_page_low(
dst = ((buf_block_t*) bpage)->frame;
}
- fil_io_t fio = fil_io(
- IORequestRead, sync, page_id, zip_size, 0,
- zip_size ? zip_size : srv_page_size,
- dst, bpage, ignore);
+ const ulint len = zip_size ? zip_size : srv_page_size;
+ auto fio = space->io(IORequest(sync
+ ? IORequest::READ_SYNC
+ : IORequest::READ_ASYNC),
+ page_id.page_no() * len, len, dst, bpage);
*err= fio.err;
if (UNIV_UNLIKELY(fio.err != DB_SUCCESS)) {
- if (ignore || fio.err == DB_TABLESPACE_DELETED) {
+ if (!sync || fio.err == DB_TABLESPACE_DELETED) {
buf_pool.corrupted_evict(bpage);
- if (sync && fio.node) {
- fio.node->space->release_for_io();
- }
- return(0);
+ return false;
}
ut_error;
@@ -360,16 +356,16 @@ buf_read_page_low(
if (sync) {
thd_wait_end(NULL);
- /* The i/o was already completed in fil_io() */
+ /* The i/o was already completed in space->io() */
*err = buf_page_read_complete(bpage, *fio.node);
- fio.node->space->release_for_io();
+ space->release();
if (*err != DB_SUCCESS) {
- return(0);
+ return false;
}
}
- return(1);
+ return true;
}
/** Applies a random read-ahead in buf_pool if there are at least a threshold
@@ -406,7 +402,7 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
if (buf_pool.n_pend_reads > buf_pool.curr_size / BUF_READ_AHEAD_PEND_LIMIT)
return 0;
- fil_space_t* space= fil_space_acquire(page_id.space());
+ fil_space_t* space= fil_space_t::get(page_id.space());
if (!space)
return 0;
@@ -414,8 +410,7 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
ulint count= 5 + buf_read_ahead_area / 8;
const page_id_t low= page_id - (page_id.page_no() % buf_read_ahead_area);
page_id_t high= low + buf_read_ahead_area;
- high.set_page_no(std::min(high.page_no(),
- static_cast<uint32_t>(space->committed_size - 1)));
+ high.set_page_no(std::min(high.page_no(), space->last_page_number()));
/* Count how many blocks in the area have been recently accessed,
that is, reside near the start of the LRU list. */
@@ -431,10 +426,14 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
goto read_ahead;
}
+no_read_ahead:
space->release();
return 0;
read_ahead:
+ if (!space->acquire_if_not_stopped())
+ goto no_read_ahead;
+
/* Read all the suitable blocks within the area */
const ulint ibuf_mode= ibuf ? BUF_READ_IBUF_PAGES_ONLY : BUF_READ_ANY_PAGE;
@@ -442,8 +441,12 @@ read_ahead:
{
if (ibuf_bitmap_page(i, zip_size))
continue;
+ if (space->is_stopping())
+ break;
dberr_t err;
- count+= buf_read_page_low(&err, false, ibuf_mode, i, zip_size, false);
+ space->reacquire();
+ if (buf_read_page_low(&err, space, false, ibuf_mode, i, zip_size, false))
+ count++;
}
if (count)
@@ -474,41 +477,40 @@ after decryption normal page checksum does not match.
@retval DB_TABLESPACE_DELETED if tablespace .ibd file is missing */
dberr_t buf_read_page(const page_id_t page_id, ulint zip_size)
{
- dberr_t err = DB_SUCCESS;
-
- ulint count = buf_read_page_low(
- &err, true, BUF_READ_ANY_PAGE, page_id, zip_size, false);
-
- srv_stats.buf_pool_reads.add(count);
-
- if (err == DB_TABLESPACE_DELETED) {
- ib::info() << "trying to read page " << page_id
- << " in nonexisting or being-dropped tablespace";
- }
+ fil_space_t *space= fil_space_t::get(page_id.space());
+ if (!space)
+ {
+ ib::info() << "trying to read page " << page_id
+ << " in nonexisting or being-dropped tablespace";
+ return DB_TABLESPACE_DELETED;
+ }
- /* Increment number of I/O operations used for LRU policy. */
- buf_LRU_stat_inc_io();
+ dberr_t err;
+ if (buf_read_page_low(&err, space, true, BUF_READ_ANY_PAGE,
+ page_id, zip_size, false))
+ srv_stats.buf_pool_reads.add(1);
- return(err);
+ buf_LRU_stat_inc_io();
+ return err;
}
/** High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread.
+@param[in,out] space tablespace
@param[in] page_id page id
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] sync true if synchronous aio is desired */
-void
-buf_read_page_background(const page_id_t page_id, ulint zip_size, bool sync)
+void buf_read_page_background(fil_space_t *space, const page_id_t page_id,
+ ulint zip_size, bool sync)
{
- ulint count;
dberr_t err;
- count = buf_read_page_low(
- &err, sync,
- BUF_READ_ANY_PAGE,
- page_id, zip_size, false, true);
+ if (buf_read_page_low(&err, space, sync, BUF_READ_ANY_PAGE,
+ page_id, zip_size, false)) {
+ srv_stats.buf_pool_reads.add(1);
+ }
switch (err) {
case DB_SUCCESS:
@@ -530,8 +532,6 @@ buf_read_page_background(const page_id_t page_id, ulint zip_size, bool sync)
<< page_id;
}
- srv_stats.buf_pool_reads.add(count);
-
/* We do not increment number of I/O operations used for LRU policy
here (buf_LRU_stat_inc_io()). We use this in heuristics to decide
about evicting uncompressed version of compressed pages from the
@@ -597,12 +597,14 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
read-ahead, as that could break the ibuf page access order */
return 0;
- fil_space_t *space= fil_space_acquire(page_id.space());
+ fil_space_t *space= fil_space_t::get(page_id.space());
if (!space)
return 0;
- if (high_1.page_no() >= space->committed_size)
+
+ if (high_1.page_no() > space->last_page_number())
{
/* The area is not whole. */
+fail:
space->release();
return 0;
}
@@ -630,8 +632,7 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
{
hard_fail:
hash_lock->read_unlock();
- space->release();
- return 0;
+ goto fail;
}
const byte *f;
switch (UNIV_EXPECT(bpage->state(), BUF_BLOCK_FILE_PAGE)) {
@@ -663,7 +664,7 @@ hard_fail:
if (id != new_low && id != new_high_1)
/* This is not a border page of the area: return */
goto hard_fail;
- if (new_high_1.page_no() >= space->committed_size)
+ if (new_high_1.page_no() > space->last_page_number())
/* The area is not whole */
goto hard_fail;
}
@@ -673,8 +674,7 @@ failed:
hash_lock->read_unlock();
if (--count)
continue;
- space->release();
- return 0;
+ goto fail;
}
const unsigned accessed= bpage->is_accessed();
@@ -701,8 +701,11 @@ failed:
{
if (ibuf_bitmap_page(new_low, zip_size))
continue;
+ if (space->is_stopping())
+ break;
dberr_t err;
- count+= buf_read_page_low(&err, false, ibuf_mode, new_low, zip_size,
+ space->reacquire();
+ count+= buf_read_page_low(&err, space, false, ibuf_mode, new_low, zip_size,
false);
}
@@ -721,35 +724,25 @@ failed:
}
/** Issues read requests for pages which recovery wants to read in.
-@param[in] sync true if the caller wants this function to wait
-for the highest address page to get read in, before this function returns
@param[in] space_id tablespace id
@param[in] page_nos array of page numbers to read, with the
highest page number the last in the array
-@param[in] n_stored number of page numbers in the array */
-void
-buf_read_recv_pages(
- bool sync,
- ulint space_id,
- const ulint* page_nos,
- ulint n_stored)
+@param[in] n number of page numbers in the array */
+void buf_read_recv_pages(ulint space_id, const uint32_t* page_nos, ulint n)
{
- fil_space_t* space = fil_space_get(space_id);
+ fil_space_t* space = fil_space_t::get(space_id);
- if (space == NULL) {
- /* The tablespace is missing: do nothing */
+ if (!space) {
+ /* The tablespace is missing or unreadable: do nothing */
return;
}
- fil_space_open_if_needed(space);
-
const ulint zip_size = space->zip_size();
- for (ulint i = 0; i < n_stored; i++) {
+ for (ulint i = 0; i < n; i++) {
/* Ignore if the page already present in freed ranges. */
- if (space->freed_ranges.contains(
- static_cast<uint32_t>(page_nos[i]))) {
+ if (space->freed_ranges.contains(page_nos[i])) {
continue;
}
@@ -774,9 +767,10 @@ buf_read_recv_pages(
}
dberr_t err;
- buf_read_page_low(
- &err, sync && i + 1 == n_stored,
- BUF_READ_ANY_PAGE, cur_page_id, zip_size, true);
+ space->reacquire();
+ buf_read_page_low(&err, space, false,
+ BUF_READ_ANY_PAGE, cur_page_id, zip_size,
+ true);
if (err == DB_DECRYPTION_FAILED || err == DB_PAGE_CORRUPTED) {
ib::error() << "Recovery failed to read or decrypt "
@@ -784,6 +778,8 @@ buf_read_recv_pages(
}
}
- DBUG_PRINT("ib_buf", ("recovery read-ahead (%u pages)",
- unsigned(n_stored)));
+
+ DBUG_PRINT("ib_buf", ("recovery read (%u pages) for %s", n,
+ space->chain.start->name));
+ space->release();
}
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 359684416ed..bd2cf4ffdd8 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -273,6 +273,11 @@ dict_boot(void)
dict_sys.row_id = DICT_HDR_ROW_ID_WRITE_MARGIN
+ ut_uint64_align_up(mach_read_from_8(dict_hdr + DICT_HDR_ROW_ID),
DICT_HDR_ROW_ID_WRITE_MARGIN);
+ if (ulint max_space_id = mach_read_from_4(dict_hdr
+ + DICT_HDR_MAX_SPACE_ID)) {
+ max_space_id--;
+ fil_assign_new_space_id(&max_space_id);
+ }
/* Insert into the dictionary cache the descriptions of the basic
system tables */
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 7a27160ccd5..55e3191c228 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -948,10 +948,10 @@ void dict_drop_index_tree(btr_pcur_t* pcur, trx_t* trx, mtr_t* mtr)
ut_ad(len == 8);
- if (fil_space_t* s = fil_space_acquire_silent(space_id)) {
+ if (fil_space_t* s = fil_space_t::get(space_id)) {
/* Ensure that the tablespace file exists
in order to avoid a crash in buf_page_get_gen(). */
- if (s->size || fil_space_get_size(space_id)) {
+ if (root_page_no < s->get_size()) {
btr_free_if_exists(page_id_t(space_id, root_page_no),
s->zip_size(),
mach_read_from_8(ptr), mtr);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index d9338af1327..ca4081e90e9 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -884,7 +884,7 @@ is_unaccessible:
return nullptr;
}
- if (!fil_table_accessible(table))
+ if (!table->is_accessible())
goto is_unaccessible;
size_t db1_len, tbl1_len;
@@ -1992,6 +1992,12 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
#ifdef BTR_CUR_HASH_ADAPT
if (UNIV_UNLIKELY(UT_LIST_GET_LEN(table->freed_indexes) != 0)) {
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ fts_free(table);
+ table->fts = NULL;
+ }
+
table->vc_templ = NULL;
table->id = 0;
return;
@@ -2353,7 +2359,6 @@ dict_index_add_col(
if (col->is_virtual()) {
dict_v_col_t* v_col = reinterpret_cast<dict_v_col_t*>(col);
/* Register the index with the virtual column index list */
- v_col->n_v_indexes++;
v_col->v_indexes.push_front(dict_v_idx_t(index, index->n_def));
col_name = dict_table_get_v_col_name_mysql(
table, dict_col_get_no(col));
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 489f4d491d1..753bcf74967 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -2975,15 +2975,15 @@ err_exit:
}
if (err == DB_SUCCESS && table->is_readable()) {
- if (table->space && !fil_space_get_size(table->space_id)) {
+ const auto root = dict_table_get_first_index(table)->page;
+
+ if (root >= table->space->get_size()) {
corrupted:
table->corrupted = true;
table->file_unreadable = true;
err = DB_CORRUPTION;
} else {
- const page_id_t page_id(
- table->space->id,
- dict_table_get_first_index(table)->page);
+ const page_id_t page_id(table->space->id, root);
mtr.start();
buf_block_t* block = buf_page_get(
page_id, table->space->zip_size(),
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 5b79406fb18..96f2d7b6e3b 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -124,25 +124,17 @@ bool dict_col_t::same_encoding(uint16_t a, uint16_t b)
return false;
}
-/** Creates a table memory object.
-@param[in] name table name
-@param[in] space tablespace
-@param[in] n_cols total number of columns including virtual and
- non-virtual columns
-@param[in] n_v_cols number of virtual columns
-@param[in] flags table flags
-@param[in] flags2 table flags2
-@param[in] init_stats_latch whether to init the stats latch
+/** Create a table memory object.
+@param name table name
+@param space tablespace
+@param n_cols total number of columns (both virtual and non-virtual)
+@param n_v_cols number of virtual columns
+@param flags table flags
+@param flags2 table flags2
@return own: table object */
-dict_table_t*
-dict_mem_table_create(
- const char* name,
- fil_space_t* space,
- ulint n_cols,
- ulint n_v_cols,
- ulint flags,
- ulint flags2,
- bool init_stats_latch)
+dict_table_t *dict_mem_table_create(const char *name, fil_space_t *space,
+ ulint n_cols, ulint n_v_cols, ulint flags,
+ ulint flags2)
{
dict_table_t* table;
mem_heap_t* heap;
@@ -210,12 +202,6 @@ dict_mem_table_create(
new(&table->foreign_set) dict_foreign_set();
new(&table->referenced_set) dict_foreign_set();
- if (init_stats_latch) {
- rw_lock_create(dict_table_stats_key, &table->stats_latch,
- SYNC_INDEX_TREE);
- table->stats_latch_inited = true;
- }
-
return(table);
}
@@ -258,10 +244,6 @@ dict_mem_table_free(
UT_DELETE(table->s_cols);
- if (table->stats_latch_inited) {
- rw_lock_free(&table->stats_latch);
- }
-
mem_heap_free(table->heap);
}
@@ -440,7 +422,6 @@ dict_mem_table_add_v_col(
/* Initialize the index list for virtual columns */
ut_ad(v_col->v_indexes.empty());
- v_col->n_v_indexes = 0;
return(v_col);
}
@@ -1211,6 +1192,24 @@ 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++)
+ {
+ const dict_col_t *col= dict_index_get_nth_col(foreign_index, i);
+ if (dict_table_is_fts_column(foreign_table->fts->indexes, col->ind,
+ col->is_virtual()) != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
+}
+
/** Reconstruct the clustered index fields. */
inline void dict_index_t::reconstruct_fields()
{
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 03330664264..07d5230b3f7 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -483,8 +483,6 @@ dict_stats_table_clone_create(
ut_d(t->magic_n = DICT_TABLE_MAGIC_N);
- rw_lock_create(dict_table_stats_key, &t->stats_latch, SYNC_INDEX_TREE);
-
return(t);
}
@@ -497,7 +495,6 @@ dict_stats_table_clone_free(
/*========================*/
dict_table_t* t) /*!< in: dummy table object to free */
{
- rw_lock_free(&t->stats_latch);
mem_heap_free(t->heap);
}
@@ -514,7 +511,7 @@ dict_stats_empty_index(
{
ut_ad(!(index->type & DICT_FTS));
ut_ad(!dict_index_is_ibuf(index));
- ut_ad(rw_lock_own(&index->table->stats_latch, RW_LOCK_X));
+ ut_ad(mutex_own(&dict_sys.mutex));
ulint n_uniq = index->n_uniq;
@@ -544,10 +541,9 @@ dict_stats_empty_table(
bool empty_defrag_stats)
/*!< in: whether to empty defrag stats */
{
- /* Zero the stats members */
-
- rw_lock_x_lock(&table->stats_latch);
+ mutex_enter(&dict_sys.mutex);
+ /* Zero the stats members */
table->stat_n_rows = 0;
table->stat_clustered_index_size = 1;
/* 1 page for each index, not counting the clustered */
@@ -571,8 +567,7 @@ dict_stats_empty_table(
}
table->stat_initialized = TRUE;
-
- rw_lock_x_unlock(&table->stats_latch);
+ mutex_exit(&dict_sys.mutex);
}
/*********************************************************************//**
@@ -671,6 +666,8 @@ dict_stats_copy(
to have the same statistics as if
the table was empty */
{
+ ut_ad(mutex_own(&dict_sys.mutex));
+
dst->stats_last_recalc = src->stats_last_recalc;
dst->stat_n_rows = src->stat_n_rows;
dst->stat_clustered_index_size = src->stat_clustered_index_size;
@@ -788,8 +785,6 @@ dict_stats_snapshot_create(
{
mutex_enter(&dict_sys.mutex);
- rw_lock_s_lock(&table->stats_latch);
-
dict_stats_assert_initialized(table);
dict_table_t* t;
@@ -803,8 +798,6 @@ dict_stats_snapshot_create(
t->stats_sample_pages = table->stats_sample_pages;
t->stats_bg_flag = table->stats_bg_flag;
- rw_lock_s_unlock(&table->stats_latch);
-
mutex_exit(&dict_sys.mutex);
return(t);
@@ -844,10 +837,14 @@ dict_stats_update_transient_for_index(
Initialize some bogus index cardinality
statistics, so that the data can be queried in
various means, also via secondary indexes. */
+ mutex_enter(&dict_sys.mutex);
dict_stats_empty_index(index, false);
+ mutex_exit(&dict_sys.mutex);
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
} else if (ibuf_debug && !dict_index_is_clust(index)) {
+ mutex_enter(&dict_sys.mutex);
dict_stats_empty_index(index, false);
+ mutex_exit(&dict_sys.mutex);
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
} else {
mtr_t mtr;
@@ -868,7 +865,9 @@ dict_stats_update_transient_for_index(
switch (size) {
case ULINT_UNDEFINED:
+ mutex_enter(&dict_sys.mutex);
dict_stats_empty_index(index, false);
+ mutex_exit(&dict_sys.mutex);
return;
case 0:
/* The root node of the tree is a leaf */
@@ -880,11 +879,23 @@ dict_stats_update_transient_for_index(
/* Do not continue if table decryption has failed or
table is already marked as corrupted. */
if (index->is_readable()) {
- /* We don't handle the return value since it
- will be false only when some thread is
- dropping the table and we don't have to empty
- the statistics of the to be dropped index */
- btr_estimate_number_of_different_key_vals(index);
+ std::vector<index_field_stats_t> stats
+ = btr_estimate_number_of_different_key_vals(
+ index);
+
+ if (!stats.empty()) {
+ ut_ad(!mutex_own(&dict_sys.mutex));
+ mutex_enter(&dict_sys.mutex);
+ for (size_t i = 0; i < stats.size(); ++i) {
+ index->stat_n_diff_key_vals[i]
+ = stats[i].n_diff_key_vals;
+ index->stat_n_sample_sizes[i]
+ = stats[i].n_sample_sizes;
+ index->stat_n_non_null_key_vals[i]
+ = stats[i].n_non_null_key_vals;
+ }
+ mutex_exit(&dict_sys.mutex);
+ }
}
}
}
@@ -901,6 +912,8 @@ dict_stats_update_transient(
/*========================*/
dict_table_t* table) /*!< in/out: table */
{
+ ut_ad(!mutex_own(&dict_sys.mutex));
+
dict_index_t* index;
ulint sum_of_index_sizes = 0;
@@ -926,27 +939,25 @@ dict_stats_update_transient(
ut_ad(!dict_index_is_ibuf(index));
- if (index->type & DICT_FTS || dict_index_is_spatial(index)) {
+ if (index->type & (DICT_FTS | DICT_SPATIAL)) {
continue;
}
- dict_stats_empty_index(index, false);
-
- if (dict_stats_should_ignore_index(index)) {
+ if (dict_stats_should_ignore_index(index)
+ || !index->is_readable()) {
+ mutex_enter(&dict_sys.mutex);
+ dict_stats_empty_index(index, false);
+ mutex_exit(&dict_sys.mutex);
continue;
}
- /* Do not continue if table decryption has failed or
- table is already marked as corrupted. */
- if (!index->is_readable()) {
- break;
- }
-
dict_stats_update_transient_for_index(index);
sum_of_index_sizes += index->stat_index_size;
}
+ mutex_enter(&dict_sys.mutex);
+
index = dict_table_get_first_index(table);
table->stat_n_rows = index->stat_n_diff_key_vals[
@@ -962,6 +973,8 @@ dict_stats_update_transient(
table->stat_modified_counter = 0;
table->stat_initialized = TRUE;
+
+ mutex_exit(&dict_sys.mutex);
}
/* @{ Pseudo code about the relation between the following functions
@@ -1807,16 +1820,31 @@ dict_stats_analyze_index_for_n_prefix(
btr_pcur_close(&pcur);
}
+/** statistics for an index */
+struct index_stats_t
+{
+ std::vector<index_field_stats_t> stats;
+ ulint index_size;
+ ulint n_leaf_pages;
+
+ index_stats_t(ulint n_uniq) : index_size(1), n_leaf_pages(1)
+ {
+ stats.reserve(n_uniq);
+ for (ulint i= 0; i < n_uniq; ++i)
+ stats.push_back(index_field_stats_t(0, 1, 0));
+ }
+};
+
/** Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[].
@param[in] n_diff_data input data to use to derive the results
-@param[in,out] index index whose stat_n_diff_key_vals[] to set */
+@param[in,out] index_stats index stats to set */
UNIV_INLINE
void
dict_stats_index_set_n_diff(
const n_diff_data_t* n_diff_data,
- dict_index_t* index)
+ index_stats_t& index_stats)
{
- for (ulint n_prefix = dict_index_get_n_unique(index);
+ for (ulint n_prefix = index_stats.stats.size();
n_prefix >= 1;
n_prefix--) {
/* n_diff_all_analyzed_pages can be 0 here if
@@ -1847,14 +1875,14 @@ dict_stats_index_set_n_diff(
that the total number of ordinary leaf pages is
T * D / (D + E). */
n_ordinary_leaf_pages
- = index->stat_n_leaf_pages
+ = index_stats.n_leaf_pages
* data->n_leaf_pages_to_analyze
/ (data->n_leaf_pages_to_analyze
+ data->n_external_pages_sum);
}
/* See REF01 for an explanation of the algorithm */
- index->stat_n_diff_key_vals[n_prefix - 1]
+ index_stats.stats[n_prefix - 1].n_diff_key_vals
= n_ordinary_leaf_pages
* data->n_diff_on_level
@@ -1863,7 +1891,7 @@ dict_stats_index_set_n_diff(
* data->n_diff_all_analyzed_pages
/ data->n_leaf_pages_to_analyze;
- index->stat_n_sample_sizes[n_prefix - 1]
+ index_stats.stats[n_prefix - 1].n_sample_sizes
= data->n_leaf_pages_to_analyze;
DEBUG_PRINTF(" %s(): n_diff=" UINT64PF
@@ -1872,9 +1900,9 @@ dict_stats_index_set_n_diff(
" * " UINT64PF " / " UINT64PF
" * " UINT64PF " / " UINT64PF ")\n",
__func__,
- index->stat_n_diff_key_vals[n_prefix - 1],
+ index_stats.stats[n_prefix - 1].n_diff_key_vals,
n_prefix,
- index->stat_n_leaf_pages,
+ index_stats.n_leaf_pages,
data->n_diff_on_level,
data->n_recs_on_level,
data->n_diff_all_analyzed_pages,
@@ -1882,15 +1910,12 @@ dict_stats_index_set_n_diff(
}
}
-/*********************************************************************//**
-Calculates new statistics for a given index and saves them to the index
+/** Calculates new statistics for a given index and saves them to the index
members stat_n_diff_key_vals[], stat_n_sample_sizes[], stat_index_size and
-stat_n_leaf_pages. This function could be slow. */
-static
-void
-dict_stats_analyze_index(
-/*=====================*/
- dict_index_t* index) /*!< in/out: index to analyze */
+stat_n_leaf_pages. This function can be slow.
+@param[in] index index to analyze
+@return index stats */
+static index_stats_t dict_stats_analyze_index(dict_index_t* index)
{
ulint root_level;
ulint level;
@@ -1901,26 +1926,28 @@ dict_stats_analyze_index(
ib_uint64_t total_pages;
mtr_t mtr;
ulint size;
+ index_stats_t result(index->n_uniq);
DBUG_ENTER("dict_stats_analyze_index");
DBUG_PRINT("info", ("index: %s, online status: %d", index->name(),
dict_index_get_online_status(index)));
+ ut_ad(!mutex_own(&dict_sys.mutex)); // because this function is slow
+ ut_ad(index->table->get_ref_count());
+
/* Disable update statistic for Rtree */
if (dict_index_is_spatial(index)) {
- DBUG_VOID_RETURN;
+ DBUG_RETURN(result);
}
DEBUG_PRINTF(" %s(index=%s)\n", __func__, index->name());
- dict_stats_empty_index(index, false);
-
mtr.start();
mtr_s_lock_index(index, &mtr);
size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr);
if (size != ULINT_UNDEFINED) {
- index->stat_index_size = size;
+ result.index_size = size;
size = btr_get_size(index, BTR_N_LEAF_PAGES, &mtr);
}
@@ -1930,13 +1957,13 @@ dict_stats_analyze_index(
switch (size) {
case ULINT_UNDEFINED:
dict_stats_assert_initialized_index(index);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(result);
case 0:
/* The root node of the tree is a leaf */
size = 1;
}
- index->stat_n_leaf_pages = size;
+ result.n_leaf_pages = size;
mtr.start();
mtr_sx_lock_index(index, &mtr);
@@ -1975,14 +2002,18 @@ dict_stats_analyze_index(
NULL /* boundaries not needed */,
&mtr);
+ mtr.commit();
+
+ mutex_enter(&dict_sys.mutex);
for (ulint i = 0; i < n_uniq; i++) {
- index->stat_n_sample_sizes[i] = total_pages;
+ result.stats[i].n_diff_key_vals = index->stat_n_diff_key_vals[i];
+ result.stats[i].n_sample_sizes = total_pages;
+ result.stats[i].n_non_null_key_vals = index->stat_n_non_null_key_vals[i];
}
+ result.n_leaf_pages = index->stat_n_leaf_pages;
+ mutex_exit(&dict_sys.mutex);
- mtr.commit();
-
- dict_stats_assert_initialized_index(index);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(result);
}
/* For each level that is being scanned in the btree, this contains the
@@ -2174,13 +2205,12 @@ found_level:
/* n_prefix == 0 means that the above loop did not end up prematurely
due to tree being changed and so n_diff_data[] is set up. */
if (n_prefix == 0) {
- dict_stats_index_set_n_diff(n_diff_data, index);
+ dict_stats_index_set_n_diff(n_diff_data, result);
}
UT_DELETE_ARRAY(n_diff_data);
- dict_stats_assert_initialized_index(index);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(result);
}
/*********************************************************************//**
@@ -2198,7 +2228,7 @@ dict_stats_update_persistent(
DEBUG_PRINTF("%s(table=%s)\n", __func__, table->name);
- rw_lock_x_lock(&table->stats_latch);
+ DEBUG_SYNC_C("dict_stats_update_persistent");
/* analyze the clustered index first */
@@ -2209,15 +2239,26 @@ dict_stats_update_persistent(
|| (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) {
/* Table definition is corrupt */
- rw_lock_x_unlock(&table->stats_latch);
dict_stats_empty_table(table, true);
return(DB_CORRUPTION);
}
ut_ad(!dict_index_is_ibuf(index));
+ mutex_enter(&dict_sys.mutex);
+ dict_stats_empty_index(index, false);
+ mutex_exit(&dict_sys.mutex);
- dict_stats_analyze_index(index);
+ index_stats_t stats = dict_stats_analyze_index(index);
+
+ mutex_enter(&dict_sys.mutex);
+ index->stat_index_size = stats.index_size;
+ index->stat_n_leaf_pages = stats.n_leaf_pages;
+ for (size_t i = 0; i < stats.stats.size(); ++i) {
+ index->stat_n_diff_key_vals[i] = stats.stats[i].n_diff_key_vals;
+ index->stat_n_sample_sizes[i] = stats.stats[i].n_sample_sizes;
+ index->stat_n_non_null_key_vals[i] = stats.stats[i].n_non_null_key_vals;
+ }
ulint n_unique = dict_index_get_n_unique(index);
@@ -2235,7 +2276,7 @@ dict_stats_update_persistent(
ut_ad(!dict_index_is_ibuf(index));
- if (index->type & DICT_FTS || dict_index_is_spatial(index)) {
+ if (index->type & (DICT_FTS | DICT_SPATIAL)) {
continue;
}
@@ -2246,7 +2287,20 @@ dict_stats_update_persistent(
}
if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) {
- dict_stats_analyze_index(index);
+ mutex_exit(&dict_sys.mutex);
+ stats = dict_stats_analyze_index(index);
+ mutex_enter(&dict_sys.mutex);
+
+ index->stat_index_size = stats.index_size;
+ index->stat_n_leaf_pages = stats.n_leaf_pages;
+ for (size_t i = 0; i < stats.stats.size(); ++i) {
+ index->stat_n_diff_key_vals[i]
+ = stats.stats[i].n_diff_key_vals;
+ index->stat_n_sample_sizes[i]
+ = stats.stats[i].n_sample_sizes;
+ index->stat_n_non_null_key_vals[i]
+ = stats.stats[i].n_non_null_key_vals;
+ }
}
table->stat_sum_of_other_index_sizes
@@ -2261,7 +2315,7 @@ dict_stats_update_persistent(
dict_stats_assert_initialized(table);
- rw_lock_x_unlock(&table->stats_latch);
+ mutex_exit(&dict_sys.mutex);
return(DB_SUCCESS);
}
@@ -3078,11 +3132,22 @@ dict_stats_update_for_index(
if (dict_stats_is_persistent_enabled(index->table)) {
if (dict_stats_persistent_storage_check(false)) {
- rw_lock_x_lock(&index->table->stats_latch);
- dict_stats_analyze_index(index);
+ index_stats_t stats = dict_stats_analyze_index(index);
+ mutex_enter(&dict_sys.mutex);
+ index->stat_index_size = stats.index_size;
+ index->stat_n_leaf_pages = stats.n_leaf_pages;
+ for (size_t i = 0; i < stats.stats.size(); ++i) {
+ index->stat_n_diff_key_vals[i]
+ = stats.stats[i].n_diff_key_vals;
+ index->stat_n_sample_sizes[i]
+ = stats.stats[i].n_sample_sizes;
+ index->stat_n_non_null_key_vals[i]
+ = stats.stats[i].n_non_null_key_vals;
+ }
index->table->stat_sum_of_other_index_sizes
+= index->stat_index_size;
- rw_lock_x_unlock(&index->table->stats_latch);
+ mutex_exit(&dict_sys.mutex);
+
dict_stats_save(index->table, &index->id);
DBUG_VOID_RETURN;
}
@@ -3103,9 +3168,7 @@ dict_stats_update_for_index(
}
}
- rw_lock_x_lock(&index->table->stats_latch);
dict_stats_update_transient_for_index(index);
- rw_lock_x_unlock(&index->table->stats_latch);
DBUG_VOID_RETURN;
}
@@ -3259,7 +3322,7 @@ dict_stats_update(
switch (err) {
case DB_SUCCESS:
- rw_lock_x_lock(&table->stats_latch);
+ mutex_enter(&dict_sys.mutex);
/* Pass reset_ignored_indexes=true as parameter
to dict_stats_copy. This will cause statictics
@@ -3268,7 +3331,7 @@ dict_stats_update(
dict_stats_assert_initialized(table);
- rw_lock_x_unlock(&table->stats_latch);
+ mutex_exit(&dict_sys.mutex);
dict_stats_table_clone_free(t);
@@ -3322,13 +3385,8 @@ dict_stats_update(
}
transient:
-
- rw_lock_x_lock(&table->stats_latch);
-
dict_stats_update_transient(table);
- rw_lock_x_unlock(&table->stats_latch);
-
return(DB_SUCCESS);
}
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 0b2e28b6476..bd7ae83b53a 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -358,7 +358,7 @@ next_table_id:
ut_ad(!table->is_temporary());
- if (!fil_table_accessible(table)) {
+ if (!table->is_accessible()) {
dict_table_close(table, TRUE, FALSE);
mutex_exit(&dict_sys.mutex);
goto next_table_id;
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 7cd939fcc54..73f87173485 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -633,7 +633,7 @@ byte* fil_space_encrypt(
return (src_frame);
}
- ut_ad(space->pending_io());
+ ut_ad(space->referenced());
return fil_encrypt_buf(space->crypt_data, space->id, offset,
src_frame, space->zip_size(),
@@ -846,7 +846,7 @@ fil_space_decrypt(
const ulint physical_size = space->physical_size();
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
- ut_ad(space->pending_io());
+ ut_ad(space->referenced());
bool encrypted = fil_space_decrypt(space->id, space->crypt_data,
tmp_frame, physical_size,
@@ -975,8 +975,7 @@ static inline
void
fil_crypt_read_crypt_data(fil_space_t* space)
{
- if (space->crypt_data || space->size
- || !fil_space_get_size(space->id)) {
+ if (space->crypt_data || space->size || !space->get_size()) {
/* The encryption metadata has already been read, or
the tablespace is not encrypted and the file has been
opened already, or the file cannot be accessed,
@@ -1009,8 +1008,6 @@ fil_crypt_read_crypt_data(fil_space_t* space)
@return true if a recheck of tablespace is needed by encryption thread. */
static bool fil_crypt_start_encrypting_space(fil_space_t* space)
{
- bool recheck = false;
-
mutex_enter(&fil_crypt_threads_mutex);
fil_space_crypt_t *crypt_data = space->crypt_data;
@@ -1022,12 +1019,9 @@ static bool fil_crypt_start_encrypting_space(fil_space_t* space)
return false;
}
- if (crypt_data != NULL || fil_crypt_start_converting) {
- /* someone beat us to it */
- if (fil_crypt_start_converting) {
- recheck = true;
- }
+ const bool recheck = fil_crypt_start_converting;
+ if (recheck || crypt_data || space->is_stopping()) {
mutex_exit(&fil_crypt_threads_mutex);
return recheck;
}
@@ -1046,54 +1040,44 @@ static bool fil_crypt_start_encrypting_space(fil_space_t* space)
return false;
}
- crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
- crypt_data->min_key_version = 0; // all pages are unencrypted
- crypt_data->rotate_state.start_time = time(0);
- crypt_data->rotate_state.starting = true;
- crypt_data->rotate_state.active_threads = 1;
-
- mutex_enter(&fil_system.mutex);
- space->crypt_data = crypt_data;
- mutex_exit(&fil_system.mutex);
-
fil_crypt_start_converting = true;
mutex_exit(&fil_crypt_threads_mutex);
- do
- {
- mtr_t mtr;
- mtr.start();
- mtr.set_named_space(space);
+ mtr_t mtr;
+ mtr.start();
- /* 2 - get page 0 */
- dberr_t err = DB_SUCCESS;
- buf_block_t* block = buf_page_get_gen(
- page_id_t(space->id, 0), space->zip_size(),
- RW_X_LATCH, NULL, BUF_GET,
- __FILE__, __LINE__,
- &mtr, &err);
+ /* 2 - get page 0 */
+ dberr_t err = DB_SUCCESS;
+ if (buf_block_t* block = buf_page_get_gen(
+ page_id_t(space->id, 0), space->zip_size(),
+ RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED,
+ __FILE__, __LINE__, &mtr, &err)) {
+
+ crypt_data->type = CRYPT_SCHEME_1;
+ crypt_data->min_key_version = 0; // all pages are unencrypted
+ crypt_data->rotate_state.start_time = time(0);
+ crypt_data->rotate_state.starting = true;
+ crypt_data->rotate_state.active_threads = 1;
+
+ mutex_enter(&fil_system.mutex);
+ const bool stopping = space->is_stopping();
+ if (!stopping) {
+ space->crypt_data = crypt_data;
+ }
+ mutex_exit(&fil_system.mutex);
+ if (stopping) {
+ goto abort;
+ }
/* 3 - write crypt data to page 0 */
- crypt_data->type = CRYPT_SCHEME_1;
+ mtr.set_named_space(space);
crypt_data->write_page0(block, &mtr);
mtr.commit();
- /* record lsn of update */
- lsn_t end_lsn = mtr.commit_lsn();
-
/* 4 - sync tablespace before publishing crypt data */
-
- bool success = false;
- ulint sum_pages = 0;
-
- do {
- ulint n_pages = 0;
- success = buf_flush_lists(ULINT_MAX, end_lsn, &n_pages);
- buf_flush_wait_batch_end(false);
- sum_pages += n_pages;
- } while (!success);
+ while (buf_flush_dirty_pages(space->id));
/* 5 - publish crypt data */
mutex_enter(&fil_crypt_threads_mutex);
@@ -1107,19 +1091,18 @@ static bool fil_crypt_start_encrypting_space(fil_space_t* space)
mutex_exit(&crypt_data->mutex);
mutex_exit(&fil_crypt_threads_mutex);
- return recheck;
- } while (0);
-
- mutex_enter(&crypt_data->mutex);
- ut_a(crypt_data->rotate_state.active_threads == 1);
- crypt_data->rotate_state.active_threads = 0;
- mutex_exit(&crypt_data->mutex);
+ return false;
+ }
+abort:
+ mtr.commit();
mutex_enter(&fil_crypt_threads_mutex);
fil_crypt_start_converting = false;
mutex_exit(&fil_crypt_threads_mutex);
- return recheck;
+ crypt_data->~fil_space_crypt_t();
+ ut_free(crypt_data);
+ return false;
}
/** State of a rotation thread */
@@ -1134,7 +1117,7 @@ struct rotate_thread_t {
uint thread_no;
bool first; /*!< is position before first space */
fil_space_t* space; /*!< current space or NULL */
- ulint offset; /*!< current offset */
+ uint32_t offset; /*!< current page number */
ulint batch; /*!< #pages to rotate */
uint min_key_version_found;/*!< min key version found but not rotated */
lsn_t end_lsn; /*!< max lsn when rotating this space */
@@ -1156,7 +1139,6 @@ struct rotate_thread_t {
case SRV_SHUTDOWN_CLEANUP:
case SRV_SHUTDOWN_INITIATED:
return true;
- case SRV_SHUTDOWN_FLUSH_PHASE:
case SRV_SHUTDOWN_LAST_PHASE:
break;
}
@@ -1493,7 +1475,7 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
while (it != end)
{
space= &*it;
- if (space->acquire())
+ if (space->acquire_if_not_stopped(true))
return space;
while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
}
@@ -1501,44 +1483,41 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
return NULL;
}
-/** Return the next tablespace.
-@param space previous tablespace (NULL to start from the beginning)
+/** Determine the next tablespace for encryption key rotation.
+@param space current tablespace (nullptr to start from the beginning)
@param recheck whether the removal condition needs to be rechecked after
-the encryption parameters were changed
+encryption parameters were changed
@param encrypt expected state of innodb_encrypt_tables
-@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, bool recheck,
- bool encrypt)
+@return the next tablespace
+@retval nullptr upon reaching the end of the iteration */
+inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
+ bool encrypt)
{
mutex_enter(&fil_system.mutex);
if (!srv_fil_crypt_rotate_key_age)
space= fil_system.keyrotate_next(space, recheck, encrypt);
- 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. */
- if (!space->acquire())
- goto next;
- }
else
{
- /* Move on to the next fil_space_t */
- space->release();
-next:
- 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_TYPE_TABLESPACE))
+ if (!space)
+ space= UT_LIST_GET_FIRST(fil_system.space_list);
+ else
+ {
+ /* Move on to the next fil_space_t */
+ space->release();
space= UT_LIST_GET_NEXT(space_list, space);
+ }
- if (space && !space->acquire())
- goto next;
+ for (; space; space= UT_LIST_GET_NEXT(space_list, space))
+ {
+ if (space->purpose != FIL_TYPE_TABLESPACE)
+ continue;
+ const uint32_t n= space->acquire_low();
+ if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
+ break;
+ if (!(n & STOPPING) && space->prepare(true))
+ break;
+ }
}
mutex_exit(&fil_system.mutex);
@@ -1582,8 +1561,8 @@ static bool fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- state->space = fil_space_next(state->space, *recheck,
- key_state->key_version != 0);
+ state->space = fil_space_t::next(state->space, *recheck,
+ key_state->key_version != 0);
while (!state->should_shutdown() && state->space) {
/* If there is no crypt data and we have not yet read
@@ -1601,8 +1580,8 @@ static bool fil_crypt_find_space_to_rotate(
return true;
}
- state->space = fil_space_next(state->space, *recheck,
- key_state->key_version != 0);
+ state->space = fil_space_t::next(state->space, *recheck,
+ key_state->key_version != 0);
}
if (state->space) {
@@ -1707,7 +1686,7 @@ fil_crypt_find_page_to_rotate(
}
}
- crypt_data->rotate_state.next_offset += batch;
+ crypt_data->rotate_state.next_offset += uint32_t(batch);
mutex_exit(&crypt_data->mutex);
return found;
}
@@ -1729,7 +1708,7 @@ static
buf_block_t*
fil_crypt_get_page_throttle_func(
rotate_thread_t* state,
- ulint offset,
+ uint32_t offset,
mtr_t* mtr,
ulint* sleeptime_ms,
const char* file,
@@ -1805,7 +1784,7 @@ fil_crypt_rotate_page(
{
fil_space_t*space = state->space;
ulint space_id = space->id;
- ulint offset = state->offset;
+ uint32_t offset = state->offset;
ulint sleeptime_ms = 0;
fil_space_crypt_t *crypt_data = space->crypt_data;
@@ -1929,9 +1908,9 @@ fil_crypt_rotate_pages(
const key_state_t* key_state,
rotate_thread_t* state)
{
- ulint space = state->space->id;
- ulint end = std::min(state->offset + state->batch,
- state->space->free_limit);
+ ulint space_id = state->space->id;
+ uint32_t end = std::min(state->offset + uint32_t(state->batch),
+ state->space->free_limit);
ut_ad(state->space->referenced());
@@ -1945,8 +1924,7 @@ fil_crypt_rotate_pages(
* real pages, they will be updated anyway when the
* real page is updated
*/
- if (space == TRX_SYS_SPACE &&
- buf_dblwr_page_inside(state->offset)) {
+ if (buf_dblwr.is_inside(page_id_t(space_id, state->offset))) {
continue;
}
@@ -1978,20 +1956,19 @@ fil_crypt_flush_space(
lsn_t end_lsn = crypt_data->rotate_state.end_lsn;
if (end_lsn > 0 && !space->is_stopping()) {
- bool success = false;
- ulint n_pages = 0;
ulint sum_pages = 0;
const ulonglong start = my_interval_timer();
-
do {
- success = buf_flush_lists(ULINT_MAX, end_lsn, &n_pages);
- buf_flush_wait_batch_end(false);
- sum_pages += n_pages;
- } while (!success && !space->is_stopping());
+ ulint n_dirty= buf_flush_dirty_pages(state->space->id);
+ if (!n_dirty) {
+ break;
+ }
+ sum_pages += n_dirty;
+ } while (!space->is_stopping());
- const ulonglong end = my_interval_timer();
+ if (sum_pages) {
+ const ulonglong end = my_interval_timer();
- if (sum_pages && end > start) {
state->cnt_waited += sum_pages;
state->sum_waited_us += (end - start) / 1000;
@@ -2016,7 +1993,7 @@ fil_crypt_flush_space(
if (buf_block_t* block = buf_page_get_gen(
page_id_t(space->id, 0), space->zip_size(),
- RW_X_LATCH, NULL, BUF_GET,
+ RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr, &err)) {
mtr.set_named_space(space);
crypt_data->write_page0(block, &mtr);
@@ -2219,11 +2196,10 @@ fil_crypt_set_thread_cnt(
uint add = new_cnt - srv_n_fil_crypt_threads;
srv_n_fil_crypt_threads = new_cnt;
for (uint i = 0; i < add; i++) {
- os_thread_id_t rotation_thread_id;
- os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id);
ib::info() << "Creating #"
<< i+1 << " encryption thread id "
- << os_thread_pf(rotation_thread_id)
+ << os_thread_pf(
+ os_thread_create(fil_crypt_thread))
<< " total threads " << new_cnt << ".";
}
} else if (new_cnt < srv_n_fil_crypt_threads) {
@@ -2257,21 +2233,12 @@ static void fil_crypt_rotation_list_fill()
if (space->purpose != FIL_TYPE_TABLESPACE
|| space->is_in_rotation_list
|| UT_LIST_GET_LEN(space->chain) == 0
- || !space->acquire()) {
+ || !space->acquire_if_not_stopped(true)) {
continue;
}
/* Ensure that crypt_data has been initialized. */
- if (!space->size) {
- ut_d(const fil_space_t* s=)
- fil_system.read_page0(space->id);
- ut_ad(!s || s == space);
- if (!space->size) {
- /* Page 0 was not loaded.
- Skip this tablespace. */
- goto next;
- }
- }
+ ut_ad(space->size);
/* Skip ENCRYPTION!=DEFAULT tablespaces. */
if (space->crypt_data
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 21743a0e076..c515cd82c48 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -49,25 +49,69 @@ Created 10/25/1995 Heikki Tuuri
#include "os0event.h"
#include "sync0sync.h"
#include "buf0flu.h"
-#include "os0api.h"
#ifdef UNIV_LINUX
# include <sys/types.h>
# include <sys/sysmacros.h>
# include <dirent.h>
#endif
-/** Tries to close a file in the LRU list. The caller must hold the fil_sys
-mutex.
-@return true if success, false if should retry later; since i/o's
-generally complete in < 100 ms, and as InnoDB writes at most 128 pages
-from the buffer pool in a batch, and then immediately flushes the
-files, there is a good chance that the next time we find a suitable
-node from the LRU list.
-@param[in] print_info if true, prints information why it
- cannot close a file */
-static
-bool
-fil_try_to_close_file_in_LRU(bool print_info);
+/** Determine if the space id is a user tablespace id or not.
+@param space_id tablespace identifier
+@return true if it is a user tablespace ID */
+inline bool fil_is_user_tablespace_id(ulint space_id)
+{
+ return space_id != TRX_SYS_SPACE && space_id != SRV_TMP_SPACE_ID &&
+ !srv_is_undo_tablespace(space_id);
+}
+
+/** Try to close a file to adhere to the innodb_open_files limit.
+@param print_info whether to diagnose why a file cannot be closed
+@return whether a file was closed */
+bool fil_space_t::try_to_close(bool print_info)
+{
+ ut_ad(mutex_own(&fil_system.mutex));
+ for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list); space;
+ space= UT_LIST_GET_NEXT(space_list, space))
+ {
+ switch (space->purpose) {
+ case FIL_TYPE_TEMPORARY:
+ continue;
+ case FIL_TYPE_IMPORT:
+ break;
+ case FIL_TYPE_TABLESPACE:
+ if (!fil_is_user_tablespace_id(space->id))
+ continue;
+ }
+
+ /* We are using an approximation of LRU replacement policy. In
+ fil_node_open_file_low(), newly opened files are moved to the end
+ of fil_system.space_list, so that they would be less likely to be
+ closed here. */
+ fil_node_t *node= UT_LIST_GET_FIRST(space->chain);
+ ut_ad(node);
+ ut_ad(!UT_LIST_GET_NEXT(chain, node));
+
+ if (!node->is_open())
+ continue;
+
+ if (const auto n= space->set_closing())
+ {
+ if (print_info)
+ ib::info() << "Cannot close file " << node->name
+ << " because of "
+ << (n & PENDING)
+ << ((n & NEEDS_FSYNC)
+ ? " pending operations and pending fsync"
+ : " pending operations");
+ continue;
+ }
+
+ node->close();
+ return true;
+ }
+
+ return false;
+}
/** Test if a tablespace file can be renamed to a new filepath by checking
if that the old filepath exists and the new filepath does not exist.
@@ -143,16 +187,7 @@ from a file, versus reading from a raw disk.
To have fast access to a tablespace or a log file, we put the data structures
to a hash table. Each tablespace and log file is given an unique 32-bit
-identifier.
-
-Some operating systems do not support many open files at the same time,
-though NT seems to tolerate at least 900 open files. Therefore, we put the
-open files in an LRU-list. If we need to open another file, we may close the
-file at the end of the LRU-list. When an i/o-operation is pending on a file,
-the file cannot be closed. We take the file nodes with pending i/o-operations
-out of the LRU-list and keep a count of pending operations. When an operation
-completes, we decrement the count and return the file node to the LRU-list if
-the count drops to zero. */
+identifier. */
/** Reference to the server data directory. Usually it is the
current working directory ".", but in the MySQL Embedded Server Library
@@ -163,7 +198,7 @@ const char* fil_path_to_mysql_datadir;
const char* dot_ext[] = { "", ".ibd", ".isl", ".cfg" };
/** Number of pending tablespace flushes */
-ulint fil_n_pending_tablespace_flushes = 0;
+Atomic_counter<ulint> fil_n_pending_tablespace_flushes;
/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
@@ -171,19 +206,6 @@ fil_system_t fil_system;
/** At this age or older a space/page will be rotated */
UNIV_INTERN extern uint srv_fil_crypt_rotate_key_age;
-UNIV_INTERN extern ib_mutex_t fil_crypt_threads_mutex;
-
-/** Determine if the space id is a user tablespace id or not.
-@param[in] space_id Space ID to check
-@return true if it is a user tablespace ID */
-inline
-bool
-fil_is_user_tablespace_id(ulint space_id)
-{
- return(space_id != TRX_SYS_SPACE
- && space_id != SRV_TMP_SPACE_ID
- && !srv_is_undo_tablespace(space_id));
-}
#ifdef UNIV_DEBUG
/** Try fil_validate() every this many times */
@@ -206,43 +228,6 @@ fil_validate_skip(void)
}
#endif /* UNIV_DEBUG */
-/********************************************************************//**
-Determines if a file node belongs to the least-recently-used list.
-@return true if the file belongs to fil_system.LRU mutex. */
-UNIV_INLINE
-bool
-fil_space_belongs_in_lru(
-/*=====================*/
- const fil_space_t* space) /*!< in: file space */
-{
- switch (space->purpose) {
- case FIL_TYPE_TEMPORARY:
- return(false);
- case FIL_TYPE_TABLESPACE:
- return(fil_is_user_tablespace_id(space->id));
- case FIL_TYPE_IMPORT:
- return(true);
- }
-
- ut_ad(0);
- return(false);
-}
-
-/********************************************************************//**
-NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
-
-Prepares a file node for i/o. Opens the file if it is closed. Updates the
-pending i/o's field in the node and the system appropriately. Takes the node
-off the LRU list if it is in the LRU list. The caller must hold the fil_sys
-mutex.
-@return false if the file can't be opened, otherwise true */
-static
-bool
-fil_node_prepare_for_io(
-/*====================*/
- fil_node_t* node, /*!< in: file node */
- fil_space_t* space); /*!< in: space */
-
/*******************************************************************//**
Returns the table space by a given id, NULL if not found.
It is unsafe to dereference the returned pointer. It is fine to check
@@ -270,8 +255,7 @@ The caller should hold an InnoDB table lock or a MDL that prevents
the tablespace from being dropped during the operation,
or the caller should be in single-threaded crash recovery mode
(no user connections that could drop tablespaces).
-If this is not the case, fil_space_acquire() and fil_space_t::release()
-should be used instead.
+Normally, fil_space_t::get() should be used instead.
@param[in] id tablespace ID
@return tablespace, or NULL if not found */
fil_space_t*
@@ -284,30 +268,6 @@ fil_space_get(
return(space);
}
-/**********************************************************************//**
-Checks if all the file nodes in a space are flushed.
-@return true if all are flushed */
-static
-bool
-fil_space_is_flushed(
-/*=================*/
- fil_space_t* space) /*!< in: space */
-{
- ut_ad(mutex_own(&fil_system.mutex));
-
- for (const fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
-
- if (node->needs_flush) {
- ut_ad(srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC);
- return(false);
- }
- }
-
- return(true);
-}
-
/** Validate the compression algorithm for full crc32 format.
@param[in] space tablespace object
@return whether the compression algorithm support */
@@ -352,11 +312,11 @@ static bool fil_comp_algo_validate(const fil_space_t* space)
@param[in] is_raw whether this is a raw device
@param[in] atomic_write true if atomic write could be enabled
@param[in] max_pages maximum number of pages in file,
-or ULINT_MAX for unlimited
+or UINT32_MAX for unlimited
@return file object */
fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle,
- ulint size, bool is_raw, bool atomic_write,
- ulint max_pages)
+ uint32_t size, bool is_raw, bool atomic_write,
+ uint32_t max_pages)
{
fil_node_t* node;
@@ -388,96 +348,113 @@ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle,
this->size += size;
UT_LIST_ADD_LAST(chain, node);
if (node->is_open()) {
- fil_system.n_open++;
+ n_pending.fetch_and(~CLOSING, std::memory_order_relaxed);
+ if (++fil_system.n_open >= srv_max_n_open_files) {
+ reacquire();
+ try_to_close(true);
+ release();
+ }
}
mutex_exit(&fil_system.mutex);
return node;
}
-/** Open a file node of a tablespace.
-@param[in,out] node File node
-@return false if the file can't be opened, otherwise true */
-static bool fil_node_open_file(fil_node_t* node)
+/** Open a tablespace file.
+@param node data file
+@return whether the file was successfully opened */
+static bool fil_node_open_file_low(fil_node_t *node)
{
- bool success;
- bool read_only_mode;
- fil_space_t* space = node->space;
-
- ut_ad(mutex_own(&fil_system.mutex));
- ut_a(node->n_pending == 0);
- ut_a(!node->is_open());
-
- read_only_mode = space->purpose != FIL_TYPE_TEMPORARY
- && srv_read_only_mode;
-
- const bool first_time_open = node->size == 0;
-
- if (first_time_open
- || (space->purpose == FIL_TYPE_TABLESPACE
- && node == UT_LIST_GET_FIRST(space->chain)
- && srv_startup_is_before_trx_rollback_phase)) {
- /* We do not know the size of the file yet. First we
- open the file in the normal mode, no async I/O here,
- for simplicity. Then do some checks, and close the
- file again. NOTE that we could not use the simple
- file read function os_file_read() in Windows to read
- from a file opened for async I/O! */
-
-retry:
- node->handle = os_file_create(
- innodb_data_file_key, node->name,
- node->is_raw_disk
- ? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
- : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
-
- if (!success) {
- /* The following call prints an error message */
- ulint err = os_file_get_last_error(true);
- if (err == EMFILE + 100) {
- if (fil_try_to_close_file_in_LRU(true))
- goto retry;
- }
-
- ib::warn() << "Cannot open '" << node->name << "'."
- " Have you deleted .ibd files under a"
- " running mysqld server?";
- return(false);
- }
-
- if (!node->read_page0(first_time_open)) {
-fail:
- os_file_close(node->handle);
- node->handle = OS_FILE_CLOSED;
- return false;
- }
+ ut_ad(!node->is_open());
+ ut_ad(node->space->is_closing());
+ ut_ad(mutex_own(&fil_system.mutex));
+ const auto flags= node->space->flags;
+ bool o_direct_possible= !FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
+ static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096, "compatibility");
+ if (const auto ssize= FSP_FLAGS_GET_ZIP_SSIZE(flags))
+ if (ssize < 3)
+ o_direct_possible= false;
+
+ for (;;)
+ {
+ bool success;
+ node->handle= os_file_create(innodb_data_file_key, node->name,
+ node->is_raw_disk
+ ? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
+ : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
+ OS_FILE_AIO, o_direct_possible
+ ? OS_DATA_FILE : OS_DATA_FILE_NO_O_DIRECT,
+ srv_read_only_mode, &success);
+ if (success)
+ break;
+
+ /* The following call prints an error message */
+ if (os_file_get_last_error(true) == EMFILE + 100 &&
+ fil_space_t::try_to_close(true))
+ continue;
- if (first_time_open && !fil_comp_algo_validate(space)) {
- goto fail;
- }
+ ib::warn() << "Cannot open '" << node->name << "'.";
+ return false;
+ }
- } else {
- node->handle = os_file_create(
- innodb_data_file_key, node->name,
- node->is_raw_disk
- ? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT
- : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_AIO, OS_DATA_FILE, read_only_mode, &success);
- }
+ if (node->size);
+ else if (!node->read_page0() || !fil_comp_algo_validate(node->space))
+ {
+ os_file_close(node->handle);
+ node->handle= OS_FILE_CLOSED;
+ return false;
+ }
- ut_a(success);
- ut_a(node->is_open());
+ ut_ad(node->is_open());
- fil_system.n_open++;
+ if (UNIV_LIKELY(!fil_system.freeze_space_list))
+ {
+ /* Move the file last in fil_system.space_list, so that
+ fil_space_t::try_to_close() should close it as a last resort. */
+ UT_LIST_REMOVE(fil_system.space_list, node->space);
+ UT_LIST_ADD_LAST(fil_system.space_list, node->space);
+ }
- if (fil_space_belongs_in_lru(space)) {
+ fil_system.n_open++;
+ return true;
+}
- /* Put the node to the LRU list */
- UT_LIST_ADD_FIRST(fil_system.LRU, node);
- }
+/** Open a tablespace file.
+@param node data file
+@return whether the file was successfully opened */
+static bool fil_node_open_file(fil_node_t *node)
+{
+ ut_ad(mutex_own(&fil_system.mutex));
+ ut_ad(!node->is_open());
+ ut_ad(fil_is_user_tablespace_id(node->space->id) ||
+ srv_operation == SRV_OPERATION_BACKUP ||
+ srv_operation == SRV_OPERATION_RESTORE ||
+ srv_operation == SRV_OPERATION_RESTORE_DELTA);
+ ut_ad(node->space->purpose != FIL_TYPE_TEMPORARY);
+ ut_ad(node->space->referenced());
+
+ for (ulint count= 0; fil_system.n_open >= srv_max_n_open_files; count++)
+ {
+ if (fil_space_t::try_to_close(count > 1))
+ count= 0;
+ else if (count >= 2)
+ {
+ ib::warn() << "innodb_open_files=" << srv_max_n_open_files
+ << " is exceeded (" << fil_system.n_open
+ << ") files stay open)";
+ break;
+ }
+ else
+ {
+ mutex_exit(&fil_system.mutex);
+ os_thread_sleep(20000);
+ /* Flush tablespaces so that we can close modified files. */
+ fil_flush_file_spaces();
+ mutex_enter(&fil_system.mutex);
+ }
+ }
- return(true);
+ return fil_node_open_file_low(node);
}
/** Close the file handle. */
@@ -503,161 +480,63 @@ pfs_os_file_t fil_node_t::detach()
void fil_node_t::prepare_to_close_or_detach()
{
ut_ad(mutex_own(&fil_system.mutex));
+ ut_ad(space->is_ready_to_close() || srv_operation == SRV_OPERATION_BACKUP ||
+ srv_operation == SRV_OPERATION_RESTORE_DELTA);
ut_a(is_open());
- ut_a(n_pending == 0);
- ut_a(n_pending_flushes == 0);
ut_a(!being_extended);
- ut_a(!needs_flush || space->purpose == FIL_TYPE_TEMPORARY ||
+ ut_a(space->is_ready_to_close() || space->purpose == FIL_TYPE_TEMPORARY ||
srv_fast_shutdown == 2 || !srv_was_started);
ut_a(fil_system.n_open > 0);
fil_system.n_open--;
-
- if (fil_space_belongs_in_lru(space))
- {
- ut_a(UT_LIST_GET_LEN(fil_system.LRU) > 0);
- UT_LIST_REMOVE(fil_system.LRU, this);
- }
}
-/** Tries to close a file in the LRU list. The caller must hold the fil_sys
-mutex.
-@return true if success, false if should retry later; since i/o's
-generally complete in < 100 ms, and as InnoDB writes at most 128 pages
-from the buffer pool in a batch, and then immediately flushes the
-files, there is a good chance that the next time we find a suitable
-node from the LRU list.
-@param[in] print_info if true, prints information why it
- cannot close a file*/
-static
-bool
-fil_try_to_close_file_in_LRU(
-
- bool print_info)
+/** Flush any writes cached by the file system. */
+inline void fil_space_t::flush_low()
{
- fil_node_t* node;
-
- ut_ad(mutex_own(&fil_system.mutex));
-
- if (print_info) {
- ib::info() << "fil_sys open file LRU len "
- << UT_LIST_GET_LEN(fil_system.LRU);
- }
-
- for (node = UT_LIST_GET_LAST(fil_system.LRU);
- node != NULL;
- node = UT_LIST_GET_PREV(LRU, node)) {
-
- if (!node->needs_flush
- && node->n_pending_flushes == 0
- && !node->being_extended) {
-
- node->close();
-
- return(true);
- }
-
- if (!print_info) {
- continue;
- }
-
- if (node->n_pending_flushes > 0) {
-
- ib::info() << "Cannot close file " << node->name
- << ", because n_pending_flushes "
- << node->n_pending_flushes;
- }
-
- if (node->needs_flush) {
- ib::warn() << "Cannot close file " << node->name
- << ", because is should be flushed first";
- }
-
- if (node->being_extended) {
- ib::info() << "Cannot close file " << node->name
- << ", because it is being extended";
- }
- }
-
- return(false);
-}
-
-/** Flush any writes cached by the file system.
-@param[in,out] space tablespace
-@param[in] metadata whether to update file system metadata */
-static void fil_flush_low(fil_space_t* space, bool metadata = false)
-{
- ut_ad(mutex_own(&fil_system.mutex));
- ut_ad(!space->is_stopping());
-
- if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC) {
- /* No need to flush. User has explicitly disabled
- buffering. */
- ut_ad(!space->is_in_unflushed_spaces);
- ut_ad(fil_space_is_flushed(space));
- ut_ad(space->n_pending_flushes == 0);
-
-#ifdef UNIV_DEBUG
- for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
- ut_ad(!node->needs_flush);
- ut_ad(node->n_pending_flushes == 0);
- }
-#endif /* UNIV_DEBUG */
-
- if (!metadata) return;
- }
-
- /* Prevent dropping of the space while we are flushing */
- space->n_pending_flushes++;
-
- for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
-
- if (!node->needs_flush) {
- continue;
- }
-
- ut_a(node->is_open());
+ ut_ad(!mutex_own(&fil_system.mutex));
- fil_n_pending_tablespace_flushes++;
-
-#ifdef _WIN32
- if (node->is_raw_disk) {
-
- goto skip_flush;
- }
-#endif /* _WIN32 */
-
- ut_a(node->is_open());
- node->n_pending_flushes++;
- node->needs_flush = false;
-
- mutex_exit(&fil_system.mutex);
-
- os_file_flush(node->handle);
-
- mutex_enter(&fil_system.mutex);
+ uint32_t n= 0;
+ while (!n_pending.compare_exchange_strong(n, (n + 1) | NEEDS_FSYNC,
+ std::memory_order_acquire,
+ std::memory_order_relaxed))
+ {
+ if (n & STOPPING)
+ return;
+ if (!(n & NEEDS_FSYNC))
+ continue;
+ if (acquire_low() & STOPPING)
+ return;
+ break;
+ }
- node->n_pending_flushes--;
-#ifdef _WIN32
-skip_flush:
-#endif /* _WIN32 */
- if (!node->needs_flush) {
- if (space->is_in_unflushed_spaces
- && fil_space_is_flushed(space)) {
-
- fil_system.unflushed_spaces.remove(*space);
- space->is_in_unflushed_spaces = false;
- }
- }
+ fil_n_pending_tablespace_flushes++;
+ for (fil_node_t *node= UT_LIST_GET_FIRST(chain); node;
+ node= UT_LIST_GET_NEXT(chain, node))
+ {
+ if (!node->is_open())
+ {
+ ut_ad(!is_in_unflushed_spaces);
+ continue;
+ }
+ IF_WIN(if (node->is_raw_disk) continue,);
+ os_file_flush(node->handle);
+ }
- fil_n_pending_tablespace_flushes--;
- }
+ if (is_in_unflushed_spaces)
+ {
+ mutex_enter(&fil_system.mutex);
+ if (is_in_unflushed_spaces)
+ {
+ is_in_unflushed_spaces= false;
+ fil_system.unflushed_spaces.remove(*this);
+ }
+ mutex_exit(&fil_system.mutex);
+ }
- space->n_pending_flushes--;
+ clear_flush();
+ release();
+ fil_n_pending_tablespace_flushes--;
}
/** Try to extend a tablespace.
@@ -671,12 +550,14 @@ bool
fil_space_extend_must_retry(
fil_space_t* space,
fil_node_t* node,
- ulint size,
+ uint32_t size,
bool* success)
{
ut_ad(mutex_own(&fil_system.mutex));
ut_ad(UT_LIST_GET_LAST(space->chain) == node);
ut_ad(size >= FIL_IBD_FILE_INITIAL_SIZE);
+ ut_ad(node->space == space);
+ ut_ad(space->referenced() || space->is_being_truncated);
*success = space->size >= size;
@@ -697,12 +578,6 @@ fil_space_extend_must_retry(
node->being_extended = true;
- if (!fil_node_prepare_for_io(node, space)) {
- /* The tablespace data file, such as .ibd file, is missing */
- node->being_extended = false;
- return(false);
- }
-
/* At this point it is safe to release fil_system.mutex. No
other thread can rename, delete, close or extend the file because
we have set the node->being_extended flag. */
@@ -710,13 +585,13 @@ fil_space_extend_must_retry(
ut_ad(size >= space->size);
- ulint last_page_no = space->size;
- const ulint file_start_page_no = last_page_no - node->size;
+ uint32_t last_page_no = space->size;
+ const uint32_t file_start_page_no = last_page_no - node->size;
- const ulint page_size = space->physical_size();
+ const unsigned page_size = space->physical_size();
- /* fil_read_first_page() expects srv_page_size bytes.
- fil_node_open_file() expects at least 4 * srv_page_size bytes.*/
+ /* Datafile::read_first_page() expects srv_page_size bytes.
+ fil_node_t::read_page0() expects at least 4 * srv_page_size bytes.*/
os_offset_t new_size = std::max(
os_offset_t(size - file_start_page_no) * page_size,
os_offset_t(FIL_IBD_FILE_INITIAL_SIZE << srv_page_size_shift));
@@ -735,7 +610,7 @@ fil_space_extend_must_retry(
os_offset_t fsize = os_file_get_size(node->handle);
ut_a(fsize != os_offset_t(-1));
- last_page_no = ulint(fsize / page_size)
+ last_page_no = uint32_t(fsize / page_size)
+ file_start_page_no;
}
mutex_enter(&fil_system.mutex);
@@ -744,13 +619,11 @@ fil_space_extend_must_retry(
node->being_extended = false;
ut_a(last_page_no - file_start_page_no >= node->size);
- ulint file_size = last_page_no - file_start_page_no;
+ uint32_t file_size = last_page_no - file_start_page_no;
space->size += file_size - node->size;
node->size = file_size;
- const ulint pages_in_MiB = node->size
- & ~ulint((1U << (20U - srv_page_size_shift)) - 1);
-
- node->complete_io();
+ const uint32_t pages_in_MiB = node->size
+ & ~uint32_t((1U << (20U - srv_page_size_shift)) - 1);
/* Keep the last data file size info up to date, rounded to
full megabytes */
@@ -758,154 +631,123 @@ fil_space_extend_must_retry(
switch (space->id) {
case TRX_SYS_SPACE:
srv_sys_space.set_last_file_size(pages_in_MiB);
- fil_flush_low(space, true);
- return(false);
+ do_flush:
+ mutex_exit(&fil_system.mutex);
+ space->flush_low();
+ mutex_enter(&fil_system.mutex);
+ break;
default:
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|| space->purpose == FIL_TYPE_IMPORT);
if (space->purpose == FIL_TYPE_TABLESPACE
&& !space->is_being_truncated) {
- fil_flush_low(space, true);
+ goto do_flush;
}
- return(false);
+ break;
case SRV_TMP_SPACE_ID:
ut_ad(space->purpose == FIL_TYPE_TEMPORARY);
srv_tmp_space.set_last_file_size(pages_in_MiB);
- return(false);
+ break;
}
+
+ return false;
}
-/** Acquire fil_system.mutex and try to make sure we can open at least one
-file while holding it. This should be called before calling
-fil_node_prepare_for_io(), because that function may need to open a file. */
-static
-fil_space_t*
-fil_mutex_enter_and_prepare_for_io(
- ulint space_id) /*!< in: space id */
+/** @return whether the file is usable for io() */
+ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex)
{
- for (ulint count = 0;;) {
- mutex_enter(&fil_system.mutex);
-
- fil_space_t* space = fil_space_get_by_id(space_id);
-
- if (!space) {
- return nullptr;
- }
+ ut_ad(referenced());
+ if (!have_mutex)
+ mutex_enter(&fil_system.mutex);
+ ut_ad(mutex_own(&fil_system.mutex));
+ fil_node_t *node= UT_LIST_GET_LAST(chain);
+ ut_ad(!id || purpose == FIL_TYPE_TEMPORARY ||
+ node == UT_LIST_GET_FIRST(chain));
- fil_node_t* node = UT_LIST_GET_LAST(space->chain);
- ut_ad(space->id == 0
- || node == UT_LIST_GET_FIRST(space->chain));
-
- if (space->id == 0) {
- /* We keep the system tablespace files always
- open; this is important in preventing
- deadlocks in this module, as a page read
- completion often performs another read from
- the insert buffer. The insert buffer is in
- tablespace 0, and we cannot end up waiting in
- this function. */
- } else if (!node || node->is_open()) {
- /* If the file is already open, no need to do
- anything; if the space does not exist, we handle the
- situation in the function which called this
- function */
- } else {
- while (fil_system.n_open >= srv_max_n_open_files) {
- /* Too many files are open */
- if (fil_try_to_close_file_in_LRU(count > 1)) {
- /* No problem */
- } else if (count >= 2) {
- ib::warn() << "innodb_open_files="
- << srv_max_n_open_files
- << " is exceeded ("
- << fil_system.n_open
- << ") files stay open)";
- break;
- } else {
- mutex_exit(&fil_system.mutex);
- os_thread_sleep(20000);
- /* Flush tablespaces so that we can
- close modified files in the LRU list */
- fil_flush_file_spaces();
-
- count++;
- mutex_enter(&fil_system.mutex);
- continue;
- }
- }
- }
+ const bool is_open= node && (node->is_open() || fil_node_open_file(node));
- ulint size = space->recv_size;
- if (UNIV_UNLIKELY(size != 0)) {
- ut_ad(node);
- bool success;
- if (fil_space_extend_must_retry(space, node, size,
- &success)) {
- continue;
- }
+ if (!is_open)
+ release();
+ else if (auto desired_size= recv_size)
+ {
+ bool success;
+ while (fil_space_extend_must_retry(this, node, desired_size, &success))
+ mutex_enter(&fil_system.mutex);
- ut_ad(mutex_own(&fil_system.mutex));
- /* Crash recovery requires the file extension
- to succeed. */
- ut_a(success);
- /* InnoDB data files cannot shrink. */
- ut_a(space->size >= size);
- if (size > space->committed_size) {
- space->committed_size = size;
- }
+ ut_ad(mutex_own(&fil_system.mutex));
+ /* Crash recovery requires the file extension to succeed. */
+ ut_a(success);
+ /* InnoDB data files cannot shrink. */
+ ut_a(size >= desired_size);
+ if (desired_size > committed_size)
+ committed_size= desired_size;
- /* There could be multiple concurrent I/O requests for
- this tablespace (multiple threads trying to extend
- this tablespace).
+ /* There could be multiple concurrent I/O requests for this
+ tablespace (multiple threads trying to extend this tablespace).
- Also, fil_space_set_recv_size_and_flags() may have been
- invoked again during the file extension while
- fil_system.mutex was not being held by us.
+ Also, fil_space_set_recv_size_and_flags() may have been invoked
+ again during the file extension while fil_system.mutex was not
+ being held by us.
- Only if space->recv_size matches what we read
- originally, reset the field. In this way, a
- subsequent I/O request will handle any pending
- fil_space_set_recv_size_and_flags(). */
+ Only if recv_size matches what we read originally, reset the
+ field. In this way, a subsequent I/O request will handle any
+ pending fil_space_set_recv_size_and_flags(). */
- if (size == space->recv_size) {
- space->recv_size = 0;
- }
- }
+ if (desired_size == recv_size)
+ {
+ recv_size= 0;
+ goto clear;
+ }
+ }
+ else
+clear:
+ n_pending.fetch_and(~CLOSING, std::memory_order_relaxed);
- return space;
- }
+ if (!have_mutex)
+ mutex_exit(&fil_system.mutex);
+ return is_open;
}
/** Try to extend a tablespace if it is smaller than the specified size.
@param[in,out] space tablespace
@param[in] size desired size in pages
@return whether the tablespace is at least as big as requested */
-bool
-fil_space_extend(
- fil_space_t* space,
- ulint size)
+bool fil_space_extend(fil_space_t *space, uint32_t size)
{
- ut_ad(!srv_read_only_mode || space->purpose == FIL_TYPE_TEMPORARY);
-
- bool success;
-
- do {
- fil_mutex_enter_and_prepare_for_io(space->id);
- } while (fil_space_extend_must_retry(
- space, UT_LIST_GET_LAST(space->chain), size,
- &success));
-
- mutex_exit(&fil_system.mutex);
- return(success);
+ ut_ad(!srv_read_only_mode || space->purpose == FIL_TYPE_TEMPORARY);
+ bool success= false;
+ const bool acquired= space->acquire();
+ mutex_enter(&fil_system.mutex);
+ if (acquired || space->is_being_truncated)
+ {
+ while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain),
+ size, &success))
+ mutex_enter(&fil_system.mutex);
+ }
+ mutex_exit(&fil_system.mutex);
+ if (acquired)
+ space->release();
+ return success;
}
/** Prepare to free a file from fil_system. */
-pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
+inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
{
ut_ad(mutex_own(&fil_system.mutex));
ut_a(magic_n == FIL_NODE_MAGIC_N);
ut_a(!being_extended);
+ if (is_open() &&
+ (space->n_pending.fetch_or(fil_space_t::CLOSING,
+ std::memory_order_acquire) &
+ fil_space_t::PENDING))
+ {
+ mutex_exit(&fil_system.mutex);
+ while (space->referenced())
+ os_thread_sleep(100);
+ mutex_enter(&fil_system.mutex);
+ }
+
while (is_open())
{
if (space->is_in_unflushed_spaces)
@@ -915,31 +757,6 @@ pfs_os_file_t fil_node_t::close_to_free(bool detach_handle)
fil_system.unflushed_spaces.remove(*space);
}
- if (n_pending)
- {
- mutex_exit(&fil_system.mutex);
- os_thread_sleep(100);
- mutex_enter(&fil_system.mutex);
- continue;
- }
-
- if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
- {
- ut_ad(!space->is_in_unflushed_spaces);
- ut_ad(fil_space_is_flushed(space));
- }
- else if (space->is_in_unflushed_spaces && fil_space_is_flushed(space))
- {
- space->is_in_unflushed_spaces= false;
- fil_system.unflushed_spaces.remove(*space);
- }
-
- if (fil_space_belongs_in_lru(space))
- {
- ut_ad(UT_LIST_GET_LEN(fil_system.LRU) > 0);
- UT_LIST_REMOVE(fil_system.LRU, this);
- }
- ut_a(!n_pending_flushes);
ut_a(!being_extended);
if (detach_handle)
{
@@ -982,7 +799,6 @@ std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
temp_space= nullptr;
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
- ut_a(space->n_pending_flushes == 0);
for (fil_node_t* node= UT_LIST_GET_FIRST(space->chain); node;
node= UT_LIST_GET_NEXT(chain, node))
@@ -1003,6 +819,7 @@ std::vector<pfs_os_file_t> fil_system_t::detach(fil_space_t *space,
handles.push_back(handle);
}
+ ut_ad(!space->referenced());
return handles;
}
@@ -1018,10 +835,10 @@ fil_space_free_low(
ut_ad(srv_fast_shutdown == 2 || !srv_was_started
|| space->max_lsn == 0);
- /* Wait for fil_space_t::release_for_io(); after
+ /* Wait for fil_space_t::release() after
fil_system_t::detach(), the tablespace cannot be found, so
- fil_space_acquire_for_io() would return NULL */
- while (space->pending_io()) {
+ fil_space_t::get() would return NULL */
+ while (space->referenced()) {
os_thread_sleep(100);
}
@@ -1072,10 +889,10 @@ fil_space_free(
}
if (!recv_recovery_is_on()) {
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
}
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
if (space->max_lsn != 0) {
ut_d(space->max_lsn = 0);
@@ -1083,7 +900,7 @@ fil_space_free(
}
if (!recv_recovery_is_on()) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
}
fil_space_free_low(space);
@@ -1092,24 +909,19 @@ fil_space_free(
return(space != NULL);
}
-/** Create a space memory object and put it to the fil_system hash table.
-Error messages are issued to the server log.
-@param[in] name tablespace name
-@param[in] id tablespace identifier
-@param[in] flags tablespace flags
-@param[in] purpose tablespace purpose
-@param[in,out] crypt_data encryption information
-@param[in] mode encryption mode
-@return pointer to created tablespace, to be filled in with fil_space_t::add()
-@retval NULL on failure (such as when the same tablespace exists) */
-fil_space_t*
-fil_space_create(
- const char* name,
- ulint id,
- ulint flags,
- fil_type_t purpose,
- fil_space_crypt_t* crypt_data,
- fil_encryption_t mode)
+/** Create a tablespace in fil_system.
+@param name tablespace name
+@param id tablespace identifier
+@param flags tablespace flags
+@param purpose tablespace purpose
+@param crypt_data encryption information
+@param mode encryption mode
+@return pointer to created tablespace, to be filled in with add()
+@retval nullptr on failure (such as when the same tablespace exists) */
+fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
+ fil_type_t purpose,
+ fil_space_crypt_t *crypt_data,
+ fil_encryption_t mode)
{
fil_space_t* space;
@@ -1119,19 +931,6 @@ fil_space_create(
DBUG_EXECUTE_IF("fil_space_create_failure", return(NULL););
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- if (space != NULL) {
- ib::error() << "Trying to add tablespace '" << name
- << "' with id " << id
- << " to the tablespace memory cache, but tablespace '"
- << space->name << "' already exists in the cache!";
- mutex_exit(&fil_system.mutex);
- return(NULL);
- }
-
/* FIXME: if calloc() is defined as an inline function that calls
memset() or bzero(), then GCC 6 -flifetime-dse can optimize it away */
space= new (ut_zalloc_nokey(sizeof(*space))) fil_space_t;
@@ -1141,25 +940,12 @@ fil_space_create(
UT_LIST_INIT(space->chain, &fil_node_t::chain);
- if ((purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT)
- && !recv_recovery_is_on()
- && id > fil_system.max_assigned_id) {
- if (!fil_system.space_id_reuse_warned) {
- fil_system.space_id_reuse_warned = true;
-
- ib::warn() << "Allocated tablespace ID " << id
- << " for " << name << ", old maximum was "
- << fil_system.max_assigned_id;
- }
-
- fil_system.max_assigned_id = id;
- }
-
space->purpose = purpose;
space->flags = flags;
space->magic_n = FIL_SPACE_MAGIC_N;
space->crypt_data = crypt_data;
+ space->n_pending.store(CLOSING, std::memory_order_relaxed);
DBUG_LOG("tablespace",
"Created metadata for " << id << " name " << name);
@@ -1184,11 +970,44 @@ fil_space_create(
space->atomic_write_supported = true;
}
+ mutex_enter(&fil_system.mutex);
+
+ if (const fil_space_t *old_space = fil_space_get_by_id(id)) {
+ ib::error() << "Trying to add tablespace '" << name
+ << "' with id " << id
+ << " to the tablespace memory cache, but tablespace '"
+ << old_space->name << "' already exists in the cache!";
+ mutex_exit(&fil_system.mutex);
+ rw_lock_free(&space->latch);
+ space->~fil_space_t();
+ ut_free(space->name);
+ ut_free(space);
+ return(NULL);
+ }
+
HASH_INSERT(fil_space_t, hash, &fil_system.spaces, id, space);
UT_LIST_ADD_LAST(fil_system.space_list, space);
- if (id < SRV_SPACE_ID_UPPER_BOUND && id > fil_system.max_assigned_id) {
+ switch (id) {
+ case 0:
+ ut_ad(!fil_system.sys_space);
+ fil_system.sys_space = space;
+ break;
+ case SRV_TMP_SPACE_ID:
+ ut_ad(!fil_system.temp_space);
+ fil_system.temp_space = space;
+ break;
+ default:
+ ut_ad(purpose != FIL_TYPE_TEMPORARY);
+ if (UNIV_LIKELY(id <= fil_system.max_assigned_id)) {
+ break;
+ }
+ if (!fil_system.space_id_reuse_warned) {
+ ib::warn() << "Allocated tablespace ID " << id
+ << " for " << name << ", old maximum was "
+ << fil_system.max_assigned_id;
+ }
fil_system.max_assigned_id = id;
}
@@ -1262,65 +1081,40 @@ fil_assign_new_space_id(
return(success);
}
-/** Trigger a call to fil_node_t::read_page0()
-@param[in] id tablespace identifier
-@return tablespace
-@retval NULL if the tablespace does not exist or cannot be read */
-fil_space_t* fil_system_t::read_page0(ulint id)
+/** Read the first page of a data file.
+@return whether the page was found valid */
+bool fil_space_t::read_page0()
{
- mutex_exit(&mutex);
-
- ut_ad(id != 0);
-
- /* It is possible that the tablespace is dropped while we are
- not holding the mutex. */
- fil_space_t* space = fil_mutex_enter_and_prepare_for_io(id);
-
- if (space == NULL || UT_LIST_GET_LEN(space->chain) == 0) {
- return(NULL);
- }
-
- /* The following code must change when InnoDB supports
- multiple datafiles per tablespace. */
- ut_a(1 == UT_LIST_GET_LEN(space->chain));
-
- fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
-
- /* It must be a single-table tablespace and we have not opened
- the file yet; the following calls will open it and update the
- size fields */
-
- if (!fil_node_prepare_for_io(node, space)) {
- /* The single-table tablespace can't be opened,
- because the ibd file is missing. */
- return(NULL);
- }
+ ut_ad(fil_system.is_initialised());
+ ut_ad(mutex_own(&fil_system.mutex));
+ if (size)
+ return true;
- node->complete_io();
+ fil_node_t *node= UT_LIST_GET_FIRST(chain);
+ if (!node)
+ return false;
+ ut_ad(!UT_LIST_GET_NEXT(chain, node));
- return space;
+ if (UNIV_UNLIKELY(acquire_low() & STOPPING))
+ {
+ ut_ad("this should not happen" == 0);
+ return false;
+ }
+ const bool ok= node->is_open() || fil_node_open_file(node);
+ release();
+ return ok;
}
-/*******************************************************************//**
-Returns a pointer to the fil_space_t that is in the memory cache
-associated with a space id. The caller must lock fil_system.mutex.
-@return file_space_t pointer, NULL if space not found */
-UNIV_INLINE
-fil_space_t*
-fil_space_get_space(
-/*================*/
- ulint id) /*!< in: space id */
+/** Look up a tablespace and ensure that its first page has been validated. */
+static fil_space_t *fil_space_get_space(ulint id)
{
- fil_space_t* space = fil_space_get_by_id(id);
- if (space == NULL || space->size != 0) {
- return(space);
- }
-
- space = fil_system.read_page0(id);
- return(space);
+ if (fil_space_t *space= fil_space_get_by_id(id))
+ if (space->read_page0())
+ return space;
+ return nullptr;
}
-void fil_space_set_recv_size_and_flags(ulint id, ulint size, uint32_t flags)
+void fil_space_set_recv_size_and_flags(ulint id, uint32_t size, uint32_t flags)
{
ut_ad(id < SRV_SPACE_ID_UPPER_BOUND);
mutex_enter(&fil_system.mutex);
@@ -1334,53 +1128,52 @@ void fil_space_set_recv_size_and_flags(ulint id, ulint size, uint32_t flags)
mutex_exit(&fil_system.mutex);
}
-/*******************************************************************//**
-Returns the size of the space in pages. The tablespace must be cached in the
-memory cache.
-@return space size, 0 if space not found */
-ulint
-fil_space_get_size(
-/*===============*/
- ulint id) /*!< in: space id */
+/** Open each file. Never invoked on .ibd files.
+@param create_new_db whether to skip the call to fil_node_t::read_page0()
+@return whether all files were opened */
+bool fil_space_t::open(bool create_new_db)
{
- fil_space_t* space;
- ulint size;
-
- ut_ad(fil_system.is_initialised());
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_space(id);
+ ut_ad(fil_system.is_initialised());
+ ut_ad(!id || create_new_db);
- size = space ? space->size : 0;
+ bool success= true;
+ bool skip_read= create_new_db;
- mutex_exit(&fil_system.mutex);
+ mutex_enter(&fil_system.mutex);
- return(size);
-}
+ for (fil_node_t *node= UT_LIST_GET_FIRST(chain); node;
+ node= UT_LIST_GET_NEXT(chain, node))
+ {
+ if (!node->is_open() && !fil_node_open_file_low(node))
+ {
+err_exit:
+ success= false;
+ break;
+ }
-/** Open each file. Only invoked on fil_system.temp_space.
-@return whether all files were opened */
-bool fil_space_t::open()
-{
- ut_ad(fil_system.is_initialised());
+ if (create_new_db)
+ continue;
+ if (skip_read)
+ {
+ size+= node->size;
+ continue;
+ }
- mutex_enter(&fil_system.mutex);
- ut_ad(this == fil_system.temp_space
- || srv_operation == SRV_OPERATION_BACKUP
- || srv_operation == SRV_OPERATION_RESTORE
- || srv_operation == SRV_OPERATION_RESTORE_DELTA);
+ if (!node->read_page0())
+ {
+ fil_system.n_open--;
+ os_file_close(node->handle);
+ node->handle= OS_FILE_CLOSED;
+ goto err_exit;
+ }
- for (fil_node_t* node = UT_LIST_GET_FIRST(chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
- if (!node->is_open() && !fil_node_open_file(node)) {
- mutex_exit(&fil_system.mutex);
- return false;
- }
- }
+ skip_read= true;
+ }
- mutex_exit(&fil_system.mutex);
- return true;
+ if (!create_new_db)
+ committed_size= size;
+ mutex_exit(&fil_system.mutex);
+ return success;
}
/** Close each file. Only invoked on fil_system.temp_space. */
@@ -1492,7 +1285,6 @@ void fil_system_t::create(ulint hash_size)
void fil_system_t::close()
{
ut_ad(this == &fil_system);
- ut_a(!UT_LIST_GET_LEN(LRU));
ut_a(unflushed_spaces.empty());
ut_a(!UT_LIST_GET_LEN(space_list));
ut_ad(!sys_space);
@@ -1514,69 +1306,8 @@ void fil_system_t::close()
#endif /* UNIV_LINUX */
}
-/** Opens all system tablespace data files. They stay open until the
-database server shutdown. This should be called at a server startup after the
-space objects for the system tablespace have been created. The
-purpose of this operation is to make sure we never run out of file descriptors
-if we need to read from the insert buffer. */
-void
-fil_open_system_tablespace_files()
-{
- fil_space_t* space;
-
- mutex_enter(&fil_system.mutex);
-
- for (space = UT_LIST_GET_FIRST(fil_system.space_list);
- space != NULL;
- space = UT_LIST_GET_NEXT(space_list, space)) {
-
- fil_node_t* node;
-
- if (fil_space_belongs_in_lru(space)) {
-
- continue;
- }
-
- for (node = UT_LIST_GET_FIRST(space->chain);
- node != NULL;
- node = UT_LIST_GET_NEXT(chain, node)) {
-
- if (!node->is_open()) {
- if (!fil_node_open_file(node)) {
- /* This func is called during server's
- startup. If some file of log or system
- tablespace is missing, the server
- can't start successfully. So we should
- assert for it. */
- ut_a(0);
- }
- }
-
- if (srv_max_n_open_files < 10 + fil_system.n_open) {
-
- ib::warn() << "You must raise the value of"
- " innodb_open_files in my.cnf!"
- " Remember that InnoDB keeps all"
- " log files and all system"
- " tablespace files open"
- " for the whole time mysqld is"
- " running, and needs to open also"
- " some .ibd files if the"
- " file-per-table storage model is used."
- " Current open files "
- << fil_system.n_open
- << ", max allowed open files "
- << srv_max_n_open_files
- << ".";
- }
- }
- }
-
- mutex_exit(&fil_system.mutex);
-}
-
/** Close all tablespace files at shutdown */
-void fil_close_all_files()
+void fil_space_t::close_all()
{
if (!fil_system.is_initialised()) {
return;
@@ -1606,20 +1337,20 @@ next:
}
for (ulint count = 10000; count--; ) {
+ if (!space->set_closing()) {
+ node->close();
+ goto next;
+ }
mutex_exit(&fil_system.mutex);
os_thread_sleep(100);
mutex_enter(&fil_system.mutex);
if (!node->is_open()) {
goto next;
}
- if (!node->n_pending) {
- node->close();
- goto next;
- }
}
ib::error() << "File '" << node->name
- << "' has " << node->n_pending
+ << "' has " << space->referenced()
<< " operations";
}
@@ -1668,16 +1399,18 @@ fil_write_flushed_lsn(
byte* buf;
ut_ad(!srv_read_only_mode);
- buf = static_cast<byte*>(aligned_malloc(srv_page_size, srv_page_size));
+ if (!fil_system.sys_space->acquire()) {
+ return DB_ERROR;
+ }
- const page_id_t page_id(TRX_SYS_SPACE, 0);
+ buf = static_cast<byte*>(aligned_malloc(srv_page_size, srv_page_size));
- fil_io_t fio = fil_io(IORequestRead, true, page_id, 0, 0,
- srv_page_size, buf, NULL);
+ auto fio = fil_system.sys_space->io(IORequestRead, 0, srv_page_size,
+ buf);
if (fio.err == DB_SUCCESS) {
- fio.node->space->release_for_io();
- mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, lsn);
+ mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
+ lsn);
ulint fsp_flags = mach_read_from_4(
buf + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
@@ -1686,67 +1419,35 @@ fil_write_flushed_lsn(
buf_flush_assign_full_crc32_checksum(buf);
}
- fio = fil_io(IORequestWrite, true, page_id, 0, 0,
- srv_page_size, buf, NULL);
+ fio = fil_system.sys_space->io(IORequestWrite,
+ 0, srv_page_size, buf);
fil_flush_file_spaces();
- }
-
- if (fio.node) {
- fio.node->space->release_for_io();
+ } else {
+ fil_system.sys_space->release();
}
aligned_free(buf);
return fio.err;
}
-/** Acquire a tablespace when it could be dropped concurrently.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@param[in] silent whether to silently ignore missing tablespaces
-@return the tablespace
-@retval NULL if missing or being deleted */
-fil_space_t* fil_space_acquire_low(ulint id, bool silent)
+/** Acquire a tablespace reference.
+@param id tablespace identifier
+@return tablespace
+@retval nullptr if the tablespace is missing or inaccessible */
+fil_space_t *fil_space_t::get(ulint id)
{
- fil_space_t* space;
-
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- if (space == NULL) {
- if (!silent) {
- ib::warn() << "Trying to access missing"
- " tablespace " << id;
- }
- } else if (!space->acquire()) {
- space = NULL;
- }
-
- mutex_exit(&fil_system.mutex);
-
- return(space);
-}
-
-/** Acquire a tablespace for reading or writing a block,
-when it could be dropped concurrently.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing */
-fil_space_t*
-fil_space_acquire_for_io(ulint id)
-{
- mutex_enter(&fil_system.mutex);
-
- fil_space_t* space = fil_space_get_by_id(id);
+ mutex_enter(&fil_system.mutex);
+ fil_space_t *space= fil_space_get_by_id(id);
+ const uint32_t n= space ? space->acquire_low() : 0;
+ mutex_exit(&fil_system.mutex);
- if (space) {
- space->acquire_for_io();
- }
+ if (n & STOPPING)
+ space= nullptr;
- mutex_exit(&fil_system.mutex);
+ if ((n & CLOSING) && !space->prepare())
+ space= nullptr;
- return(space);
+ return space;
}
/** Write a log record about a file operation.
@@ -1980,25 +1681,21 @@ fil_check_pending_io(
ulint count) /*!< in: number of attempts so far */
{
ut_ad(mutex_own(&fil_system.mutex));
- ut_ad(!space->referenced());
/* The following code must change when InnoDB supports
multiple datafiles per tablespace. */
- ut_a(UT_LIST_GET_LEN(space->chain) == 1);
+ ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
*node = UT_LIST_GET_FIRST(space->chain);
- if (space->n_pending_flushes > 0 || (*node)->n_pending > 0) {
-
+ if (const uint32_t p = space->referenced()) {
ut_a(!(*node)->being_extended);
/* Give a warning every 10 second, starting after 1 second */
if ((count % 500) == 50) {
ib::info() << "Trying to delete"
" tablespace '" << space->name
- << "' but there are "
- << space->n_pending_flushes
- << " flushes and " << (*node)->n_pending
+ << "' but there are " << p
<< " pending i/o's on it.";
}
@@ -2026,13 +1723,14 @@ fil_check_pending_operations(
fil_space_t* sp = fil_space_get_by_id(id);
if (sp) {
- if (sp->crypt_data && sp->acquire()) {
+ sp->set_stopping(true);
+ if (sp->crypt_data) {
+ sp->reacquire();
mutex_exit(&fil_system.mutex);
fil_space_crypt_close_tablespace(sp);
mutex_enter(&fil_system.mutex);
sp->release();
}
- sp->set_stopping(true);
}
/* Check for pending operations. */
@@ -2102,12 +1800,14 @@ void fil_close_tablespace(ulint id)
rw_lock_x_lock(&space->latch);
/* Invalidate in the buffer pool all pages belonging to the
- tablespace. Since we have set space->stop_new_ops = true, readahead
+ tablespace. Since we have invoked space->set_stopping(), readahead
can no longer read more pages of this tablespace to buf_pool.
Thus we can clean the tablespace out of buf_pool
- completely and permanently. The flag stop_new_ops also prevents
- fil_flush() from being applied to this tablespace. */
- buf_LRU_flush_or_remove_pages(id, true);
+ completely and permanently. */
+ while (buf_flush_dirty_pages(id));
+ /* Ensure that all asynchronous IO is completed. */
+ os_aio_wait_until_no_pending_writes();
+ ut_ad(space->is_stopping());
/* If the free is successful, the X lock will be released before
the space memory data structure is freed. */
@@ -2127,27 +1827,6 @@ void fil_close_tablespace(ulint id)
ut_free(path);
}
-/** Determine whether a table can be accessed in operations that are
-not (necessarily) protected by meta-data locks.
-(Rollback would generally be protected, but rollback of
-FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks
-but only by InnoDB table locks, which may be broken by
-lock_remove_all_on_table().)
-@param[in] table persistent table
-checked @return whether the table is accessible */
-bool fil_table_accessible(const dict_table_t* table)
-{
- if (UNIV_UNLIKELY(!table->is_readable() || table->corrupted)) {
- return(false);
- }
-
- mutex_enter(&fil_system.mutex);
- bool accessible = table->space && !table->space->is_stopping();
- mutex_exit(&fil_system.mutex);
- ut_ad(accessible || dict_table_is_file_per_table(table));
- return accessible;
-}
-
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
@param[in] if_exists whether to ignore missing tablespace
@@ -2185,7 +1864,7 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
when we checked it above.
A write request can be issued any time because we don't check
- the ::stop_new_ops flag when queueing a block for write.
+ fil_space_t::is_stopping() when queueing a block for write.
We deal with pending write requests in the following function
where we'd minimally evict all dirty pages belonging to this
@@ -2193,10 +1872,10 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
we'll wait for IO to complete.
To deal with potential read requests, we will check the
- ::stop_new_ops flag in fil_io(). */
+ is_stopping() in fil_space_t::io(). */
err = DB_SUCCESS;
- buf_LRU_flush_or_remove_pages(id, false);
+ buf_flush_remove_pages(id);
/* If it is a delete then also delete any generated files, otherwise
when we drop the database the remove directory will fail. */
@@ -2241,14 +1920,14 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
}
mutex_exit(&fil_system.mutex);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (space->max_lsn != 0) {
ut_d(space->max_lsn = 0);
UT_LIST_REMOVE(fil_system.named_spaces, space);
}
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
fil_space_free_low(space);
if (!os_file_delete(innodb_data_file_key, path)
@@ -2513,7 +2192,7 @@ fil_rename_tablespace(
multiple datafiles per tablespace. */
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
node = UT_LIST_GET_FIRST(space->chain);
- ut_a(space->acquire());
+ space->reacquire();
mutex_exit(&fil_system.mutex);
@@ -2529,11 +2208,11 @@ fil_rename_tablespace(
if (!recv_recovery_is_on()) {
fil_name_write_rename(id, old_file_name, new_file_name);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
}
/* log_sys.mutex is above fil_system.mutex in the latching order */
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
mutex_enter(&fil_system.mutex);
space->release();
ut_ad(space->name == old_space_name);
@@ -2555,7 +2234,7 @@ skip_second_rename:
}
if (!recv_recovery_is_on()) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
}
ut_ad(space->name == old_space_name);
@@ -2597,7 +2276,7 @@ fil_ibd_create(
const char* name,
const char* path,
ulint flags,
- ulint size,
+ uint32_t size,
fil_encryption_t mode,
uint32_t key_id,
dberr_t* err)
@@ -2623,10 +2302,7 @@ fil_ibd_create(
file = os_file_create(
innodb_data_file_key, path,
OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT,
- OS_FILE_NORMAL,
- OS_DATA_FILE,
- srv_read_only_mode,
- &success);
+ OS_FILE_AIO, OS_DATA_FILE, srv_read_only_mode, &success);
if (!success) {
/* The following call will print an error message */
@@ -2652,7 +2328,7 @@ fil_ibd_create(
const bool is_compressed = fil_space_t::is_compressed(flags);
bool punch_hole = is_compressed;
-
+ fil_space_crypt_t* crypt_data = nullptr;
#ifdef _WIN32
if (is_compressed) {
os_file_set_sparse_win32(file);
@@ -2666,6 +2342,7 @@ fil_ibd_create(
err_exit:
os_file_close(file);
os_file_delete(innodb_data_file_key, path);
+ free(crypt_data);
return NULL;
}
@@ -2698,8 +2375,7 @@ err_exit:
/* Create crypt data if the tablespace is either encrypted or user has
requested it to remain unencrypted. */
- fil_space_crypt_t *crypt_data = (mode != FIL_ENCRYPTION_DEFAULT
- || srv_encrypt_tables)
+ crypt_data = (mode != FIL_ENCRYPTION_DEFAULT || srv_encrypt_tables)
? fil_space_create_crypt_data(mode, key_id)
: NULL;
@@ -2722,14 +2398,14 @@ err_exit:
buf_flush_init_for_writing(NULL, page, &page_zip, false);
- *err = os_file_write(
- IORequestWrite, path, file, page_zip.data, 0, zip_size);
+ *err = os_file_write(IORequestWrite, path, file,
+ page_zip.data, 0, zip_size);
} else {
buf_flush_init_for_writing(NULL, page, NULL,
fil_space_t::full_crc32(flags));
- *err = os_file_write(
- IORequestWrite, path, file, page, 0, srv_page_size);
+ *err = os_file_write(IORequestWrite, path, file,
+ page, 0, srv_page_size);
}
aligned_free(page);
@@ -2757,17 +2433,11 @@ err_exit:
}
}
- fil_space_t* space = fil_space_create(name, space_id, flags,
- FIL_TYPE_TABLESPACE,
- crypt_data, mode);
- if (!space) {
- free(crypt_data);
- *err = DB_ERROR;
- } else {
+ if (fil_space_t* space = fil_space_t::create(name, space_id, flags,
+ FIL_TYPE_TABLESPACE,
+ crypt_data, mode)) {
space->punch_hole = punch_hole;
- /* FIXME: Keep the file open! */
- fil_node_t* node = space->add(path, OS_FILE_CLOSED, size,
- false, true);
+ fil_node_t* node = space->add(path, file, size, false, true);
mtr_t mtr;
mtr.start();
mtr.log_file_op(FILE_CREATE, space_id, node->name);
@@ -2775,19 +2445,15 @@ err_exit:
node->find_metadata(file);
*err = DB_SUCCESS;
+ return space;
}
- os_file_close(file);
-
- if (*err != DB_SUCCESS) {
- if (has_data_dir) {
- RemoteDatafile::delete_link_file(name);
- }
-
- os_file_delete(innodb_data_file_key, path);
+ if (has_data_dir) {
+ RemoteDatafile::delete_link_file(name);
}
- return space;
+ *err = DB_ERROR;
+ goto err_exit;
}
/** Try to open a single-table tablespace and optionally check that the
@@ -3137,7 +2803,7 @@ skip_validate:
first_page)
: NULL;
- fil_space_t* space = fil_space_create(
+ fil_space_t* space = fil_space_t::create(
tablename.m_name, id, flags, purpose, crypt_data);
if (!space) {
goto error;
@@ -3151,11 +2817,17 @@ skip_validate:
df_dict.is_open() ? df_dict.filepath() :
df_default.filepath(), OS_FILE_CLOSED, 0, false, true);
- if (validate && purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
+ if (validate && !srv_read_only_mode) {
df_remote.close();
df_dict.close();
df_default.close();
- fsp_flags_try_adjust(space, flags & ~FSP_FLAGS_MEM_MASK);
+ if (space->acquire()) {
+ if (purpose != FIL_TYPE_IMPORT) {
+ fsp_flags_try_adjust(space, flags
+ & ~FSP_FLAGS_MEM_MASK);
+ }
+ space->release();
+ }
}
if (err) *err = DB_SUCCESS;
@@ -3485,7 +3157,7 @@ fil_ibd_load(
? fil_space_read_crypt_data(fil_space_t::zip_size(flags),
first_page)
: NULL;
- space = fil_space_create(
+ space = fil_space_t::create(
file.name(), space_id, flags, FIL_TYPE_TABLESPACE, crypt_data);
if (space == NULL) {
@@ -3551,7 +3223,7 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
return;
}
if (!space->size && (space->purpose != FIL_TYPE_TABLESPACE
- || !fil_space_get_size(space->id))) {
+ || !space->get_size())) {
return;
}
/* This code is executed during server startup while no
@@ -3562,7 +3234,7 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
if (buf_block_t* b = buf_page_get(
page_id_t(space->id, 0), space->zip_size(),
RW_X_LATCH, &mtr)) {
- ulint f = fsp_header_get_flags(b->frame);
+ uint32_t f = fsp_header_get_flags(b->frame);
if (fil_space_t::full_crc32(f)) {
goto func_exit;
}
@@ -3578,8 +3250,9 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
<< " to " << ib::hex(flags);
}
mtr.set_named_space(space);
- mtr.write<4>(*b, FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
- + b->frame, flags);
+ mtr.write<4,mtr_t::FORCED>(*b,
+ FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
+ + b->frame, flags);
}
func_exit:
mtr.commit();
@@ -3589,7 +3262,7 @@ func_exit:
memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
-@param[in] name Tablespace name used in fil_space_create().
+@param[in] name Tablespace name used in fil_space_t::create().
@param[in] table_flags table flags
@return the tablespace
@retval NULL if no matching tablespace exists in the memory cache */
@@ -3641,443 +3314,215 @@ func_exit:
/*============================ FILE I/O ================================*/
-/********************************************************************//**
-NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
-
-Prepares a file node for i/o. Opens the file if it is closed. Updates the
-pending i/o's field in the node and the system appropriately. Takes the node
-off the LRU list if it is in the LRU list. The caller must hold the fil_sys
-mutex.
-@return false if the file can't be opened, otherwise true */
-static
-bool
-fil_node_prepare_for_io(
-/*====================*/
- fil_node_t* node, /*!< in: file node */
- fil_space_t* space) /*!< in: space */
-{
- ut_ad(node && space);
- ut_ad(mutex_own(&fil_system.mutex));
-
- if (fil_system.n_open > srv_max_n_open_files + 5) {
- ib::warn() << "Open files " << fil_system.n_open
- << " exceeds the limit " << srv_max_n_open_files;
- }
-
- if (!node->is_open()) {
- /* File is closed: open it */
- ut_a(node->n_pending == 0);
-
- if (!fil_node_open_file(node)) {
- return(false);
- }
- }
-
- if (node->n_pending++ == 0 && fil_space_belongs_in_lru(space)) {
- UT_LIST_REMOVE(fil_system.LRU, node);
- }
-
- return(true);
-}
-
/** Report information about an invalid page access. */
ATTRIBUTE_COLD __attribute__((noreturn))
static void
-fil_report_invalid_page_access(const page_id_t id, const char *name,
- ulint byte_offset, ulint len, bool is_read)
+fil_report_invalid_page_access(const char *name,
+ os_offset_t offset, ulint len, bool is_read)
{
- ib::fatal()
- << "Trying to " << (is_read ? "read " : "write ")
- << id
- << " which is outside the bounds of tablespace " << name
- << ". Byte offset " << byte_offset << ", len " << len;
+ ib::fatal() << "Trying to " << (is_read ? "read " : "write ") << len
+ << " bytes at " << offset
+ << " outside the bounds of the file: " << name;
}
-inline void IORequest::set_fil_node(fil_node_t* node)
+
+/** Update the data structures on write completion */
+inline void fil_node_t::complete_write()
{
- if (!node->space->punch_hole) {
- clear_punch_hole();
- }
+ ut_ad(!mutex_own(&fil_system.mutex));
- m_fil_node = node;
+ if (space->purpose != FIL_TYPE_TEMPORARY &&
+ srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC &&
+ space->set_needs_flush())
+ {
+ mutex_enter(&fil_system.mutex);
+ if (!space->is_in_unflushed_spaces)
+ {
+ space->is_in_unflushed_spaces= true;
+ fil_system.unflushed_spaces.push_front(*space);
+ }
+ mutex_exit(&fil_system.mutex);
+ }
}
-/** Reads or writes data. This operation could be asynchronous (aio).
-
-@param[in,out] type IO context
-@param[in] sync true if synchronous aio is desired
-@param[in] page_id page id
-@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
-@param[in] byte_offset remainder of offset in bytes; in aio this
- must be divisible by the OS block size
-@param[in] len how many bytes to read or write; this must
- not cross a file boundary; in aio this must
- be a block size multiple
-@param[in,out] buf buffer where to store read data or from where
- to write; in aio this must be appropriately
- aligned
-@param[in] message message for aio handler if non-sync aio
- used, else ignored
-@param[in] ignore whether to ignore errors
-@param[in] punch_hole punch the hole to the file for page_compressed
- tablespace
+/** Read or write data.
+@param type I/O context
+@param offset offset in bytes
+@param len number of bytes
+@param buf the data to be read or written
+@param bpage buffer block (for type.is_async() completion callback)
@return status and file descriptor */
-fil_io_t
-fil_io(
- const IORequest& type,
- bool sync,
- const page_id_t page_id,
- ulint zip_size,
- ulint byte_offset,
- ulint len,
- void* buf,
- void* message,
- bool ignore,
- bool punch_hole)
+fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
+ void *buf, buf_page_t *bpage)
{
- os_offset_t offset;
- IORequest req_type(type);
-
- ut_ad(req_type.validate());
-
- ut_ad(len > 0);
- ut_ad(byte_offset < srv_page_size);
- ut_ad(!zip_size || byte_offset == 0);
- ut_ad(srv_page_size == 1UL << srv_page_size_shift);
- compile_time_assert((1U << UNIV_PAGE_SIZE_SHIFT_MAX)
- == UNIV_PAGE_SIZE_MAX);
- compile_time_assert((1U << UNIV_PAGE_SIZE_SHIFT_MIN)
- == UNIV_PAGE_SIZE_MIN);
+ ut_ad(referenced());
+ ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
ut_ad(fil_validate_skip());
+ ut_ad(type.is_read() || type.is_write());
+ ut_ad(type.type != IORequest::DBLWR_BATCH);
- /* ibuf bitmap pages must be read in the sync AIO mode: */
- ut_ad(recv_no_ibuf_operations
- || req_type.is_write()
- || !ibuf_bitmap_page(page_id, zip_size)
- || sync);
-
- ulint mode;
-
- if (sync) {
- mode = OS_AIO_SYNC;
- } else if (req_type.is_read()
- && !recv_no_ibuf_operations
- && ibuf_page(page_id, zip_size, NULL)) {
- mode = OS_AIO_IBUF;
- } else {
- mode = OS_AIO_NORMAL;
- }
-
- if (req_type.is_read()) {
-
+ if (type.is_read()) {
srv_stats.data_read.add(len);
-
- } else if (req_type.is_write()) {
-
- ut_ad(!srv_read_only_mode
- || fsp_is_system_temporary(page_id.space()));
-
+ } else {
+ ut_ad(!srv_read_only_mode || this == fil_system.temp_space);
srv_stats.data_written.add(len);
}
- /* Acquire fil_system.mutex and make sure that we can open at
- least one file while holding it, if the file is not already open */
- fil_space_t* space = fil_mutex_enter_and_prepare_for_io(
- page_id.space());
-
- if (!space
- || (req_type.is_read()
- && !sync
- && space->is_stopping()
- && !space->is_being_truncated)) {
-
- mutex_exit(&fil_system.mutex);
- if (!ignore) {
- ib::error()
- << "Trying to do I/O to a tablespace which"
- " does not exist. I/O type: "
- << (req_type.is_read() ? "read" : "write")
- << ", page: " << page_id
- << ", I/O length: " << len << " bytes";
- }
+ fil_node_t* node= UT_LIST_GET_FIRST(chain);
+ ut_ad(node);
+ if (type.type == IORequest::READ_ASYNC && is_stopping()
+ && !is_being_truncated) {
+ release();
return {DB_TABLESPACE_DELETED, nullptr};
}
- ulint cur_page_no = page_id.page_no();
- fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
-
- for (;;) {
-
- if (node == NULL) {
- if (ignore) {
- mutex_exit(&fil_system.mutex);
- return {DB_ERROR, nullptr};
- }
-
- fil_report_invalid_page_access(
- page_id, space->name, byte_offset, len,
- req_type.is_read());
-
- } else if (fil_is_user_tablespace_id(space->id)
- && node->size == 0) {
-
- /* We do not know the size of a single-table tablespace
- before we open the file */
- break;
-
- } else if (node->size > cur_page_no) {
- /* Found! */
- break;
+ ulint p = static_cast<ulint>(offset >> srv_page_size_shift);
- } else {
- cur_page_no -= node->size;
+ if (UNIV_LIKELY_NULL(UT_LIST_GET_NEXT(chain, node))) {
+ ut_ad(this == fil_system.sys_space
+ || this == fil_system.temp_space);
+ ut_ad(!(offset & ((1 << srv_page_size_shift) - 1)));
+ while (node->size <= p) {
+ p -= node->size;
node = UT_LIST_GET_NEXT(chain, node);
- }
- }
-
- /* Open file if closed */
- if (UNIV_UNLIKELY(!fil_node_prepare_for_io(node, space))) {
- ut_ad(fil_is_user_tablespace_id(space->id));
- mutex_exit(&fil_system.mutex);
-
- if (!ignore) {
- ib::error()
- << "Trying to do I/O to a tablespace '"
- << space->name
- << "' which exists without .ibd data file."
- " I/O type: "
- << (req_type.is_read()
- ? "read" : "write")
- << ", page: "
- << page_id
- << ", I/O length: " << len << " bytes";
+ if (!node) {
+ if (type.type == IORequest::READ_ASYNC) {
+ release();
+ return {DB_ERROR, nullptr};
+ }
+ fil_report_invalid_page_access(name, offset,
+ len,
+ type.is_read());
+ }
}
- return {DB_TABLESPACE_DELETED, nullptr};
+ offset = os_offset_t{p} << srv_page_size_shift;
}
- if (node->size <= cur_page_no) {
- if (ignore) {
+ if (UNIV_UNLIKELY(node->size <= p)) {
+ if (type.type == IORequest::READ_ASYNC) {
+ release();
/* If we can tolerate the non-existent pages, we
should return with DB_ERROR and let caller decide
what to do. */
- node->complete_io(req_type.is_write());
- mutex_exit(&fil_system.mutex);
return {DB_ERROR, nullptr};
}
fil_report_invalid_page_access(
- page_id, space->name, byte_offset, len,
- req_type.is_read());
+ node->name, offset, len, type.is_read());
}
- space->acquire_for_io();
- /* Now we have made the changes in the data structures of fil_system */
- mutex_exit(&fil_system.mutex);
-
- if (!zip_size) zip_size = srv_page_size;
-
- offset = os_offset_t(cur_page_no) * zip_size + byte_offset;
- ut_ad(node->size - cur_page_no >= (len + (zip_size - 1)) / zip_size);
-
- /* Do AIO */
-
- ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
-
- const char* name = node->name == NULL ? space->name : node->name;
-
- req_type.set_fil_node(node);
-
- ut_ad(!req_type.is_write()
- || !fil_is_user_tablespace_id(page_id.space())
- || offset == page_id.page_no() * zip_size);
-
- dberr_t err = DB_SUCCESS;
+ dberr_t err;
- if (punch_hole) {
- /* Punch the hole to the file */
+ if (type.type == IORequest::PUNCH_RANGE) {
err = os_file_punch_hole(node->handle, offset, len);
/* Punch hole is not supported, make space not to
support punch hole */
if (UNIV_UNLIKELY(err == DB_IO_NO_PUNCH_HOLE)) {
- node->space->punch_hole = false;
+ punch_hole = false;
err = DB_SUCCESS;
}
+ goto release_sync_write;
} else {
/* Queue the aio request */
- err = os_aio(
- req_type,
- mode, name, node->handle, buf, offset, len,
- space->purpose != FIL_TYPE_TEMPORARY
- && srv_read_only_mode,
- node, message);
+ err = os_aio(IORequest(bpage, node, type.type),
+ buf, offset, len);
}
/* We an try to recover the page from the double write buffer if
the decompression fails or the page is corrupt. */
- ut_a(req_type.is_dblwr_recover() || err == DB_SUCCESS);
- if (sync) {
- mutex_enter(&fil_system.mutex);
- node->complete_io(req_type.is_write());
- mutex_exit(&fil_system.mutex);
+ ut_a(type.type == IORequest::DBLWR_RECOVER || err == DB_SUCCESS);
+ if (!type.is_async()) {
+ if (type.is_write()) {
+release_sync_write:
+ node->complete_write();
+release:
+ release();
+ }
ut_ad(fil_validate_skip());
}
+ if (err != DB_SUCCESS) {
+ goto release;
+ }
return {err, node};
}
#include <tpool.h>
/** Callback for AIO completion */
-void fil_aio_callback(os_aio_userdata_t *data)
+void fil_aio_callback(const IORequest &request)
{
ut_ad(fil_validate_skip());
+ ut_ad(request.node);
- fil_node_t *node= data->node;
-
- if (UNIV_UNLIKELY(!node))
+ if (!request.bpage)
{
- ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
- return;
- }
-
- ut_ad(data->type.validate());
-
- buf_page_t *bpage= static_cast<buf_page_t*>(data->message);
- if (!bpage)
- {
- /* Asynchronous single page writes from the doublewrite buffer,
- or calls from buf_flush_freed_page() don't have access to the page. */
- ut_ad(data->type.is_write());
ut_ad(!srv_read_only_mode);
+ if (request.type == IORequest::DBLWR_BATCH)
+ buf_dblwr.flush_buffered_writes_completed(request);
+ else
+ ut_ad(request.type == IORequest::WRITE_ASYNC);
write_completed:
- mutex_enter(&fil_system.mutex);
- node->complete_io(true);
- mutex_exit(&fil_system.mutex);
- node->space->release_for_io();
- return;
+ request.node->complete_write();
}
-
- if (data->type.is_write())
+ else if (request.is_write())
{
- ut_ad(!srv_read_only_mode || node->space->purpose == FIL_TYPE_TEMPORARY);
- bool dblwr= node->space->use_doublewrite();
- if (dblwr && bpage->status == buf_page_t::INIT_ON_FLUSH)
- {
- bpage->status= buf_page_t::NORMAL;
- dblwr= false;
- }
- buf_page_write_complete(bpage, data->type, dblwr, false);
+ buf_page_write_complete(request);
goto write_completed;
}
-
- ut_ad(data->type.is_read());
-
- /* IMPORTANT: since i/o handling for reads will read also the insert
- buffer in fil_system.sys_space, we have to be very careful not to
- introduce deadlocks. We never close the system tablespace (0) data
- files via fil_system.LRU and we use a dedicated I/O thread to serve
- change buffer requests. */
- const page_id_t id(bpage->id());
-
- if (dberr_t err= buf_page_read_complete(bpage, *node))
+ else
{
- if (recv_recovery_is_on() && !srv_force_recovery)
- recv_sys.found_corrupt_fs= true;
-
- ib::error() << "Failed to read page " << id.page_no()
- << " from file '" << node->name << "': " << err;
- }
+ ut_ad(request.is_read());
- mutex_enter(&fil_system.mutex);
- node->complete_io();
- mutex_exit(&fil_system.mutex);
- node->space->release_for_io();
-}
+ /* IMPORTANT: since i/o handling for reads will read also the insert
+ buffer in fil_system.sys_space, we have to be very careful not to
+ introduce deadlocks. We never close fil_system.sys_space data
+ files and never issue asynchronous reads of change buffer pages. */
+ const page_id_t id(request.bpage->id());
-/**********************************************************************//**
-Flushes to disk possible writes cached by the OS. If the space does not exist
-or is being dropped, does not do anything. */
-void
-fil_flush(
-/*======*/
- ulint space_id) /*!< in: file space id (this can be a group of
- log files or a tablespace of the database) */
-{
- mutex_enter(&fil_system.mutex);
-
- if (fil_space_t* space = fil_space_get_by_id(space_id)) {
- if (space->purpose != FIL_TYPE_TEMPORARY
- && !space->is_stopping()) {
- fil_flush_low(space);
- }
- }
-
- mutex_exit(&fil_system.mutex);
-}
+ if (dberr_t err= buf_page_read_complete(request.bpage, *request.node))
+ {
+ if (recv_recovery_is_on() && !srv_force_recovery)
+ recv_sys.found_corrupt_fs= true;
-/** Flush a tablespace.
-@param[in,out] space tablespace to flush */
-void
-fil_flush(fil_space_t* space)
-{
- ut_ad(space->pending_io());
- ut_ad(space->purpose == FIL_TYPE_TABLESPACE
- || space->purpose == FIL_TYPE_IMPORT);
+ ib::error() << "Failed to read page " << id.page_no()
+ << " from file '" << request.node->name << "': " << err;
+ }
+ }
- if (!space->is_stopping()) {
- mutex_enter(&fil_system.mutex);
- if (!space->is_stopping()) {
- fil_flush_low(space);
- }
- mutex_exit(&fil_system.mutex);
- }
+ request.node->space->release();
}
/** Flush to disk the writes in file spaces of the given type
possibly cached by the OS. */
void fil_flush_file_spaces()
{
- ulint* space_ids;
- ulint n_space_ids;
-
- mutex_enter(&fil_system.mutex);
-
- n_space_ids = fil_system.unflushed_spaces.size();
- if (n_space_ids == 0) {
-
- mutex_exit(&fil_system.mutex);
- return;
- }
-
- space_ids = static_cast<ulint*>(
- ut_malloc_nokey(n_space_ids * sizeof(*space_ids)));
-
- n_space_ids = 0;
-
- for (sized_ilist<fil_space_t, unflushed_spaces_tag_t>::iterator it
- = fil_system.unflushed_spaces.begin(),
- end = fil_system.unflushed_spaces.end();
- it != end; ++it) {
-
- if (it->purpose == FIL_TYPE_TABLESPACE && !it->is_stopping()) {
- space_ids[n_space_ids++] = it->id;
- }
- }
-
- mutex_exit(&fil_system.mutex);
+ if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
+ {
+ ut_d(mutex_enter(&fil_system.mutex));
+ ut_ad(fil_system.unflushed_spaces.empty());
+ ut_d(mutex_exit(&fil_system.mutex));
+ return;
+ }
- /* Flush the spaces. It will not hurt to call fil_flush() on
- a non-existing space id. */
- for (ulint i = 0; i < n_space_ids; i++) {
+rescan:
+ mutex_enter(&fil_system.mutex);
- fil_flush(space_ids[i]);
- }
+ for (fil_space_t &space : fil_system.unflushed_spaces)
+ {
+ if (space.needs_flush_not_stopping())
+ {
+ mutex_exit(&fil_system.mutex);
+ space.flush_low();
+ goto rescan;
+ }
+ }
- ut_free(space_ids);
+ mutex_exit(&fil_system.mutex);
}
/** Functor to validate the file node list of a tablespace. */
@@ -4094,7 +3539,6 @@ struct Check {
@param[in] elem file node to visit */
void operator()(const fil_node_t* elem)
{
- ut_a(elem->is_open() || !elem->n_pending);
n_open += elem->is_open();
size += elem->size;
}
@@ -4131,7 +3575,6 @@ Checks the consistency of the tablespace cache.
@return true if ok */
bool fil_validate()
{
- fil_node_t* fil_node;
ulint n_open = 0;
mutex_enter(&fil_system.mutex);
@@ -4144,18 +3587,6 @@ bool fil_validate()
ut_a(fil_system.n_open == n_open);
- ut_list_validate(fil_system.LRU);
-
- for (fil_node = UT_LIST_GET_FIRST(fil_system.LRU);
- fil_node != 0;
- fil_node = UT_LIST_GET_NEXT(LRU, fil_node)) {
-
- ut_a(fil_node->n_pending == 0);
- ut_a(!fil_node->being_extended);
- ut_a(fil_node->is_open());
- ut_a(fil_space_belongs_in_lru(fil_node->space));
- }
-
mutex_exit(&fil_system.mutex);
return(true);
@@ -4240,7 +3671,7 @@ void
fil_names_dirty(
fil_space_t* space)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(recv_recovery_is_on());
ut_ad(log_sys.get_lsn() != 0);
ut_ad(space->max_lsn == 0);
@@ -4256,7 +3687,7 @@ fil_names_clear().
@param[in,out] space tablespace */
void fil_names_dirty_and_write(fil_space_t* space)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_d(fil_space_validate_for_mtr_commit(space));
ut_ad(space->max_lsn == log_sys.get_lsn());
@@ -4297,7 +3728,7 @@ fil_names_clear(
mtr_checkpoint_size = 75 * 1024;
);
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(lsn);
mtr.start();
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index a8f04a754b4..57164113647 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -296,20 +296,18 @@ Datafile::read_first_page(bool read_only_mode)
m_first_page = static_cast<byte*>(
aligned_malloc(UNIV_PAGE_SIZE_MAX, srv_page_size));
- IORequest request;
dberr_t err = DB_ERROR;
size_t page_size = UNIV_PAGE_SIZE_MAX;
/* Don't want unnecessary complaints about partial reads. */
- request.disable_partial_io_warnings();
-
while (page_size >= UNIV_PAGE_SIZE_MIN) {
ulint n_read = 0;
err = os_file_read_no_error_handling(
- request, m_handle, m_first_page, 0, page_size, &n_read);
+ IORequestReadPartial, m_handle, m_first_page, 0,
+ page_size, &n_read);
if (err == DB_IO_ERROR && n_read >= UNIV_PAGE_SIZE_MIN) {
@@ -805,10 +803,8 @@ Datafile::restore_from_doublewrite()
<< physical_size << " bytes into file '"
<< m_filepath << "'";
- IORequest request(IORequest::WRITE);
-
return(os_file_write(
- request,
+ IORequestWrite,
m_filepath, m_handle, page, 0, physical_size)
!= DB_SUCCESS);
}
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 6ac57ca395c..ae8c557b24c 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -45,7 +45,7 @@ Created 11/29/1995 Heikki Tuuri
// JAN: MySQL 5.7 Encryption
// #include <my_aes.h>
-typedef ulint page_no_t;
+typedef uint32_t page_no_t;
/** Return an extent to the free list of a space.
@param[in,out] space tablespace
@@ -111,7 +111,7 @@ fseg_alloc_free_page_low(
fil_space_t* space,
fseg_inode_t* seg_inode,
buf_block_t* iblock,
- ulint hint,
+ uint32_t hint,
byte direction,
#ifdef UNIV_DEBUG
bool has_done_reservation,
@@ -169,28 +169,29 @@ Find a free page.
@param descr extent descriptor
@param hint page offset to start searching from (towards larger pages)
@return free page offset
-@retval ULINT_UNDEFINED if no page is free */
-inline ulint xdes_find_free(const xdes_t *descr, ulint hint= 0)
+@retval FIL_NULL if no page is free */
+inline uint32_t xdes_find_free(const xdes_t *descr, uint32_t hint= 0)
{
- ut_ad(hint < FSP_EXTENT_SIZE);
- for (ulint i= hint; i < FSP_EXTENT_SIZE; i++)
+ const uint32_t extent_size= FSP_EXTENT_SIZE;
+ ut_ad(hint < extent_size);
+ for (uint32_t i= hint; i < extent_size; i++)
if (xdes_is_free(descr, i))
return i;
- for (ulint i= 0; i < hint; i++)
+ for (uint32_t i= 0; i < hint; i++)
if (xdes_is_free(descr, i))
return i;
- return ULINT_UNDEFINED;
+ return FIL_NULL;
}
/**
Determine the number of used pages in a descriptor.
@param descr file descriptor
@return number of pages used */
-inline ulint xdes_get_n_used(const xdes_t *descr)
+inline uint32_t xdes_get_n_used(const xdes_t *descr)
{
- ulint count= 0;
+ uint32_t count= 0;
- for (ulint i= 0; i < FSP_EXTENT_SIZE; ++i)
+ for (uint32_t i= FSP_EXTENT_SIZE; i--; )
if (!xdes_is_free(descr, i))
count++;
@@ -317,16 +318,14 @@ xdes_get_descriptor_with_space_hdr(
mtr_t* mtr,
bool init_space = false)
{
- ulint limit;
- ulint size;
- ulint descr_page_no;
ut_ad(mtr->memo_contains(*space));
ut_ad(mtr->memo_contains_flagged(header, MTR_MEMO_PAGE_SX_FIX
| MTR_MEMO_PAGE_X_FIX));
/* Read free limit and space size */
- limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
- + header->frame);
- size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + header->frame);
+ uint32_t limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + header->frame);
+ uint32_t size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + header->frame);
ut_ad(limit == space->free_limit
|| (space->free_limit == 0
&& (init_space
@@ -340,9 +339,9 @@ xdes_get_descriptor_with_space_hdr(
return(NULL);
}
- const ulint zip_size = space->zip_size();
+ const unsigned zip_size = space->zip_size();
- descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
+ uint32_t descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
buf_block_t* block = header;
@@ -455,17 +454,12 @@ xdes_lst_get_descriptor(
/********************************************************************//**
Returns page offset of the first page in extent described by a descriptor.
@return offset of the first page in extent */
-UNIV_INLINE
-ulint
-xdes_get_offset(
-/*============*/
- const xdes_t* descr) /*!< in: extent descriptor */
+static uint32_t xdes_get_offset(const xdes_t *descr)
{
- ut_ad(descr);
-
- return(page_get_page_no(page_align(descr))
- + ((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE)
- * FSP_EXTENT_SIZE);
+ ut_ad(descr);
+ return page_get_page_no(page_align(descr)) +
+ uint32_t(((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE) *
+ FSP_EXTENT_SIZE);
}
/** Initialize a file page whose prior contents should be ignored.
@@ -548,16 +542,23 @@ fsp_header_init_fields(
@param[in,out] space tablespace
@param[in] size current size in blocks
@param[in,out] mtr mini-transaction */
-void fsp_header_init(fil_space_t* space, ulint size, mtr_t* mtr)
+void fsp_header_init(fil_space_t* space, uint32_t size, mtr_t* mtr)
{
const page_id_t page_id(space->id, 0);
const ulint zip_size = space->zip_size();
+ buf_block_t *free_block = buf_LRU_get_free_block(false);
+
mtr_x_lock_space(space, mtr);
- buf_block_t* block = buf_page_create(space, 0, zip_size, mtr);
+ buf_block_t* block = buf_page_create(space, 0, zip_size, mtr,
+ free_block);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
+ if (UNIV_UNLIKELY(block != free_block)) {
+ buf_pool.free_block(free_block);
+ }
+
space->size_in_header = size;
space->free_len = 0;
space->free_limit = 0;
@@ -581,10 +582,11 @@ void fsp_header_init(fil_space_t* space, ulint size, mtr_t* mtr)
+ block->frame, size);
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ block->frame));
- mtr->write<4,mtr_t::MAYBE_NOP>(*block,
- FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
- + block->frame,
- space->flags & ~FSP_FLAGS_MEM_MASK);
+ if (auto f = space->flags & ~FSP_FLAGS_MEM_MASK) {
+ mtr->write<4,mtr_t::FORCED>(*block,
+ FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
+ + block->frame, f);
+ }
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_FRAG_N_USED
+ block->frame));
@@ -620,7 +622,7 @@ static ATTRIBUTE_COLD __attribute__((warn_unused_result))
bool
fsp_try_extend_data_file_with_pages(
fil_space_t* space,
- ulint page_no,
+ uint32_t page_no,
buf_block_t* header,
mtr_t* mtr)
{
@@ -651,9 +653,9 @@ fsp_try_extend_data_file_with_pages(
/** Calculate the number of physical pages in an extent for this file.
@param[in] physical_size page_size of the datafile
@return number of pages in an extent for this file */
-inline ulint fsp_get_extent_size_in_pages(ulint physical_size)
+inline uint32_t fsp_get_extent_size_in_pages(ulint physical_size)
{
- return (FSP_EXTENT_SIZE << srv_page_size_shift) / physical_size;
+ return uint32_t((FSP_EXTENT_SIZE << srv_page_size_shift) / physical_size);
}
@@ -669,12 +671,13 @@ on one extent descriptor page. See xdes_calc_descriptor_page().
@param[in] physical_size page size in data file
@param[in] size current number of pages in the datafile
@return number of pages to extend the file. */
-static ulint fsp_get_pages_to_extend_ibd(ulint physical_size, ulint size)
+static uint32_t fsp_get_pages_to_extend_ibd(unsigned physical_size,
+ uint32_t size)
{
- ulint extent_size = fsp_get_extent_size_in_pages(physical_size);
+ uint32_t extent_size = fsp_get_extent_size_in_pages(physical_size);
/* The threshold is set at 32MiB except when the physical page
size is small enough that it must be done sooner. */
- ulint threshold = std::min(32 * extent_size, physical_size);
+ uint32_t threshold = std::min(32 * extent_size, physical_size);
if (size >= threshold) {
/* Below in fsp_fill_free_list() we assume
@@ -697,8 +700,6 @@ static
ulint
fsp_try_extend_data_file(fil_space_t *space, buf_block_t *header, mtr_t *mtr)
{
- ulint size; /* current number of pages in the datafile */
- ulint size_increase; /* number of pages to extend this file */
const char* OUT_OF_SPACE_MSG =
"ran out of space. Please add another file or use"
" 'autoextend' for the last file in setting";
@@ -735,10 +736,12 @@ fsp_try_extend_data_file(fil_space_t *space, buf_block_t *header, mtr_t *mtr)
return(0);
}
- size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + header->frame);
+ uint32_t size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + header->frame);
ut_ad(size == space->size_in_header);
+ uint32_t size_increase;
- const ulint ps = space->physical_size();
+ const unsigned ps = space->physical_size();
switch (space->id) {
case TRX_SYS_SPACE:
@@ -748,7 +751,7 @@ fsp_try_extend_data_file(fil_space_t *space, buf_block_t *header, mtr_t *mtr)
size_increase = srv_tmp_space.get_increment();
break;
default:
- ulint extent_pages = fsp_get_extent_size_in_pages(ps);
+ uint32_t extent_pages = fsp_get_extent_size_in_pages(ps);
if (size < extent_pages) {
/* Let us first extend the file to extent_size */
if (!fsp_try_extend_data_file_with_pages(
@@ -818,18 +821,13 @@ fsp_fill_free_list(
buf_block_t* header,
mtr_t* mtr)
{
- ulint limit;
- ulint size;
- xdes_t* descr;
- ulint count = 0;
- ulint i;
-
ut_d(space->modify_check(*mtr));
/* Check if we can fill free list from above the free list limit */
- size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + header->frame);
- limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
- + header->frame);
+ uint32_t size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + header->frame);
+ uint32_t limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + header->frame);
ut_ad(size == space->size_in_header);
ut_ad(limit == space->free_limit);
@@ -853,17 +851,18 @@ fsp_fill_free_list(
}
}
- i = limit;
-
- while ((init_space && i < 1)
- || ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) {
+ uint32_t count = 0;
- const bool init_xdes = 0
- == ut_2pow_remainder(i, ulint(space->physical_size()));
+ for (uint32_t i = limit, extent_size = FSP_EXTENT_SIZE,
+ physical_size = space->physical_size();
+ (init_space && i < 1)
+ || (i + extent_size <= size && count < FSP_FREE_ADD);
+ i += extent_size) {
+ const bool init_xdes = !ut_2pow_remainder(i, physical_size);
- space->free_limit = i + FSP_EXTENT_SIZE;
+ space->free_limit = i + extent_size;
mtr->write<4>(*header, FSP_HEADER_OFFSET + FSP_FREE_LIMIT
- + header->frame, i + FSP_EXTENT_SIZE);
+ + header->frame, i + extent_size);
if (init_xdes) {
@@ -874,11 +873,14 @@ fsp_fill_free_list(
pages should be ignored. */
if (i > 0) {
+ buf_block_t *f= buf_LRU_get_free_block(false);
block= buf_page_create(
space, static_cast<uint32_t>(i),
- zip_size, mtr);
-
+ zip_size, mtr, f);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
+ if (UNIV_UNLIKELY(block != f)) {
+ buf_pool.free_block(f);
+ }
fsp_init_file_page(space, block, mtr);
mtr->write<2>(*block,
FIL_PAGE_TYPE + block->frame,
@@ -886,13 +888,16 @@ fsp_fill_free_list(
}
if (space->purpose != FIL_TYPE_TEMPORARY) {
+ buf_block_t *f= buf_LRU_get_free_block(false);
block = buf_page_create(
space,
static_cast<uint32_t>(
i + FSP_IBUF_BITMAP_OFFSET),
- zip_size, mtr);
+ zip_size, mtr, f);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
-
+ if (UNIV_UNLIKELY(block != f)) {
+ buf_pool.free_block(f);
+ }
fsp_init_file_page(space, block, mtr);
mtr->write<2>(*block,
block->frame + FIL_PAGE_TYPE,
@@ -901,7 +906,7 @@ fsp_fill_free_list(
}
buf_block_t* xdes;
- descr = xdes_get_descriptor_with_space_hdr(
+ xdes_t* descr = xdes_get_descriptor_with_space_hdr(
header, space, i, &xdes, mtr, init_space);
if (xdes != header && !space->full_crc32()) {
fil_block_check_type(*xdes, FIL_PAGE_TYPE_XDES, mtr);
@@ -933,8 +938,6 @@ fsp_fill_free_list(
xdes, xoffset, mtr);
count++;
}
-
- i += FSP_EXTENT_SIZE;
}
space->free_len += count;
@@ -951,7 +954,7 @@ static
xdes_t*
fsp_alloc_free_extent(
fil_space_t* space,
- ulint hint,
+ uint32_t hint,
buf_block_t** xdes,
mtr_t* mtr)
{
@@ -1042,8 +1045,11 @@ static
buf_block_t*
fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
{
+ buf_block_t *free_block= buf_LRU_get_free_block(false);
buf_block_t *block= buf_page_create(space, static_cast<uint32_t>(offset),
- space->zip_size(), mtr);
+ space->zip_size(), mtr, free_block);
+ if (UNIV_UNLIKELY(block != free_block))
+ buf_pool.free_block(free_block);
fsp_init_file_page(space, block, mtr);
return block;
}
@@ -1060,13 +1066,12 @@ static MY_ATTRIBUTE((warn_unused_result, nonnull))
buf_block_t*
fsp_alloc_free_page(
fil_space_t* space,
- ulint hint,
+ uint32_t hint,
mtr_t* mtr,
mtr_t* init_mtr)
{
fil_addr_t first;
xdes_t* descr;
- ulint free;
const ulint space_id = space->id;
ut_d(space->modify_check(*mtr));
@@ -1117,8 +1122,8 @@ fsp_alloc_free_page(
/* Now we have in descr an extent with at least one free page. Look
for a free page in the extent. */
- free = xdes_find_free(descr, hint % FSP_EXTENT_SIZE);
- if (free == ULINT_UNDEFINED) {
+ uint32_t free = xdes_find_free(descr, hint % FSP_EXTENT_SIZE);
+ if (free == FIL_NULL) {
ut_print_buf(stderr, ((byte*) descr) - 500, 1000);
putc('\n', stderr);
@@ -1126,10 +1131,10 @@ fsp_alloc_free_page(
ut_error;
}
- page_no_t page_no = xdes_get_offset(descr) + free;
+ uint32_t page_no = xdes_get_offset(descr) + free;
- page_no_t space_size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
- + block->frame);
+ uint32_t space_size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + block->frame);
ut_ad(space_size == space->size_in_header
|| (space_id == TRX_SYS_SPACE
&& srv_startup_is_before_trx_rollback_phase));
@@ -1529,7 +1534,7 @@ fseg_inode_get(
@param n slot index
@return page number
@retval FIL_NULL if not in use */
-static ulint fseg_get_nth_frag_page_no(const fseg_inode_t *inode, ulint n)
+static uint32_t fseg_get_nth_frag_page_no(const fseg_inode_t *inode, ulint n)
{
ut_ad(inode);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
@@ -1636,7 +1641,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr,
{
fseg_inode_t* inode;
ib_id_t seg_id;
- ulint n_reserved;
+ uint32_t n_reserved;
DBUG_ENTER("fseg_create");
@@ -1792,7 +1797,7 @@ fseg_fill_free_list(
fseg_inode_t* inode,
buf_block_t* iblock,
fil_space_t* space,
- ulint hint,
+ uint32_t hint,
mtr_t* mtr)
{
xdes_t* descr;
@@ -1929,7 +1934,7 @@ fseg_alloc_free_page_low(
fil_space_t* space,
fseg_inode_t* seg_inode,
buf_block_t* iblock,
- ulint hint,
+ uint32_t hint,
byte direction,
#ifdef UNIV_DEBUG
bool has_done_reservation,
@@ -1942,7 +1947,7 @@ fseg_alloc_free_page_low(
ulint used;
ulint reserved;
xdes_t* descr; /*!< extent of the hinted page */
- ulint ret_page; /*!< the allocated page offset, FIL_NULL
+ uint32_t ret_page; /*!< the allocated page offset, FIL_NULL
if could not be allocated */
xdes_t* ret_descr; /*!< the extent of the allocated page */
buf_block_t* xdes;
@@ -2044,9 +2049,12 @@ take_hinted_page:
segment)
========*/
ret_descr = descr;
- ret_page = xdes_get_offset(ret_descr)
- + xdes_find_free(ret_descr, hint % FSP_EXTENT_SIZE);
- ut_ad(!has_done_reservation || ret_page != FIL_NULL);
+ ret_page = xdes_find_free(ret_descr, hint % FSP_EXTENT_SIZE);
+ if (ret_page == FIL_NULL) {
+ ut_ad(!has_done_reservation);
+ } else {
+ ret_page += xdes_get_offset(ret_descr);
+ }
/*-----------------------------------------------------------*/
} else if (reserved - used > 0) {
/* 5. We take any unused page from the segment
@@ -2063,9 +2071,12 @@ take_hinted_page:
}
ret_descr = xdes_lst_get_descriptor(space, first, &xdes, mtr);
- ret_page = xdes_get_offset(ret_descr)
- + xdes_find_free(ret_descr);
- ut_ad(!has_done_reservation || ret_page != FIL_NULL);
+ ret_page = xdes_find_free(ret_descr);
+ if (ret_page == FIL_NULL) {
+ ut_ad(!has_done_reservation);
+ } else {
+ ret_page += xdes_get_offset(ret_descr);
+ }
/*-----------------------------------------------------------*/
} else if (used < FSEG_FRAG_LIMIT) {
/* 6. We allocate an individual page from the space
@@ -2164,7 +2175,7 @@ buf_block_t*
fseg_alloc_free_page_general(
/*=========================*/
fseg_header_t* seg_header,/*!< in/out: segment header */
- ulint hint, /*!< in: hint of which page would be
+ uint32_t hint, /*!< in: hint of which page would be
desirable */
byte direction,/*!< in: if the new page is needed because
of an index page split, and records are
@@ -2185,7 +2196,7 @@ fseg_alloc_free_page_general(
fil_space_t* space;
buf_block_t* iblock;
buf_block_t* block;
- ulint n_reserved;
+ uint32_t n_reserved;
space_id = page_get_space_id(page_align(seg_header));
space = mtr_x_lock_space(space_id, mtr);
@@ -2238,10 +2249,9 @@ fsp_reserve_free_pages(
buf_block_t* header,
ulint size,
mtr_t* mtr,
- ulint n_pages)
+ uint32_t n_pages)
{
xdes_t* descr;
- ulint n_used;
ut_a(!is_system_tablespace(space->id));
ut_a(size < FSP_EXTENT_SIZE);
@@ -2249,7 +2259,7 @@ fsp_reserve_free_pages(
buf_block_t* xdes;
descr = xdes_get_descriptor_with_space_hdr(header, space, 0, &xdes,
mtr);
- n_used = xdes_get_n_used(descr);
+ uint32_t n_used = xdes_get_n_used(descr);
ut_a(n_used <= size);
@@ -2298,64 +2308,64 @@ free pages available.
@return true if we were able to make the reservation */
bool
fsp_reserve_free_extents(
- ulint* n_reserved,
+ uint32_t* n_reserved,
fil_space_t* space,
- ulint n_ext,
+ uint32_t n_ext,
fsp_reserve_t alloc_type,
mtr_t* mtr,
- ulint n_pages)
+ uint32_t n_pages)
{
- ulint n_free_list_ext;
- ulint free_limit;
- ulint size;
- ulint n_free;
- ulint n_free_up;
ulint reserve;
size_t total_reserved = 0;
ut_ad(mtr);
*n_reserved = n_ext;
+ const uint32_t extent_size = FSP_EXTENT_SIZE;
+
mtr_x_lock_space(space, mtr);
- const ulint physical_size = space->physical_size();
+ const unsigned physical_size = space->physical_size();
buf_block_t* header = fsp_get_header(space, mtr);
try_again:
- size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE + header->frame);
+ uint32_t size = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + header->frame);
ut_ad(size == space->size_in_header);
- if (size < FSP_EXTENT_SIZE && n_pages < FSP_EXTENT_SIZE / 2) {
+ if (size < extent_size && n_pages < extent_size / 2) {
/* Use different rules for small single-table tablespaces */
*n_reserved = 0;
return(fsp_reserve_free_pages(space, header, size,
mtr, n_pages));
}
- n_free_list_ext = flst_get_len(FSP_HEADER_OFFSET + FSP_FREE
- + header->frame);
+ uint32_t n_free_list_ext = flst_get_len(FSP_HEADER_OFFSET + FSP_FREE
+ + header->frame);
ut_ad(space->free_len == n_free_list_ext);
- free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
- + header->frame);
+ uint32_t free_limit = mach_read_from_4(FSP_HEADER_OFFSET
+ + FSP_FREE_LIMIT
+ + header->frame);
ut_ad(space->free_limit == free_limit);
/* Below we play safe when counting free extents above the free limit:
some of them will contain extent descriptor pages, and therefore
will not be free extents */
+ uint32_t n_free_up;
+
if (size >= free_limit) {
- n_free_up = (size - free_limit) / FSP_EXTENT_SIZE;
+ n_free_up = (size - free_limit) / extent_size;
+ if (n_free_up) {
+ n_free_up--;
+ n_free_up -= n_free_up / (physical_size / extent_size);
+ }
} else {
ut_ad(alloc_type == FSP_BLOB);
n_free_up = 0;
}
- if (n_free_up > 0) {
- n_free_up--;
- n_free_up -= n_free_up / (physical_size / FSP_EXTENT_SIZE);
- }
-
- n_free = n_free_list_ext + n_free_up;
+ uint32_t n_free = n_free_list_ext + n_free_up;
switch (alloc_type) {
case FSP_NORMAL:
@@ -2363,7 +2373,7 @@ try_again:
and 1 extent + 0.5 % to cleaning operations; NOTE: this source
code is duplicated in the function below! */
- reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200;
+ reserve = 2 + ((size / extent_size) * 2) / 200;
if (n_free <= reserve + n_ext) {
@@ -2373,7 +2383,7 @@ try_again:
case FSP_UNDO:
/* We reserve 0.5 % of the space size to cleaning operations */
- reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200;
+ reserve = 1 + ((size / extent_size) * 1) / 200;
if (n_free <= reserve + n_ext) {
@@ -2425,10 +2435,12 @@ fseg_free_page_low(
ut_ad(iblock->frame == page_align(seg_inode));
ut_d(space->modify_check(*mtr));
+ const uint32_t extent_size = FSP_EXTENT_SIZE;
+ ut_ad(ut_is_2pow(extent_size));
buf_block_t* xdes;
xdes_t* descr = xdes_get_descriptor(space, offset, &xdes, mtr);
- if (xdes_is_free(descr, offset % FSP_EXTENT_SIZE)) {
+ if (xdes_is_free(descr, offset & (extent_size - 1))) {
ib::fatal() << "InnoDB is trying to free page "
<< page_id_t(space->id, offset)
<< " though it is already marked as free in the"
@@ -2489,7 +2501,7 @@ fseg_free_page_low(
flst_add_last(iblock, static_cast<uint16_t>(FSEG_NOT_FULL
+ ioffset),
xdes, xoffset, mtr);
- not_full_n_used += FSP_EXTENT_SIZE - 1;
+ not_full_n_used += extent_size - 1;
} else {
ut_a(not_full_n_used > 0);
not_full_n_used--;
@@ -2497,7 +2509,7 @@ fseg_free_page_low(
mtr->write<4>(*iblock, p_not_full, not_full_n_used);
- const ulint bit = offset % FSP_EXTENT_SIZE;
+ const ulint bit = offset & (extent_size - 1);
xdes_set_free<true>(*xdes, descr, bit, mtr);
@@ -2521,7 +2533,7 @@ void
fseg_free_page(
fseg_header_t* seg_header,
fil_space_t* space,
- ulint offset,
+ uint32_t offset,
mtr_t* mtr)
{
DBUG_ENTER("fseg_free_page");
@@ -2584,7 +2596,7 @@ fseg_free_extent(
fseg_inode_t* seg_inode,
buf_block_t* iblock,
fil_space_t* space,
- ulint page,
+ uint32_t page,
mtr_t* mtr)
{
@@ -2598,7 +2610,7 @@ fseg_free_extent(
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
ut_d(space->modify_check(*mtr));
- const ulint first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
+ const uint32_t first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
const uint16_t xoffset= uint16_t(descr - xdes->frame + XDES_FLST_NODE);
const uint16_t ioffset= uint16_t(seg_inode - iblock->frame);
@@ -2613,9 +2625,9 @@ fseg_free_extent(
flst_remove(iblock, static_cast<uint16_t>(FSEG_NOT_FULL
+ ioffset),
xdes, xoffset, mtr);
- ulint not_full_n_used = mach_read_from_4(
+ uint32_t not_full_n_used = mach_read_from_4(
FSEG_NOT_FULL_N_USED + seg_inode);
- ulint descr_n_used = xdes_get_n_used(descr);
+ uint32_t descr_n_used = xdes_get_n_used(descr);
ut_a(not_full_n_used >= descr_n_used);
mtr->write<4>(*iblock, seg_inode + FSEG_NOT_FULL_N_USED,
not_full_n_used - descr_n_used);
@@ -2647,15 +2659,12 @@ fseg_free_step(
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
- ulint page;
fseg_inode_t* inode;
- ulint space_id;
- ulint header_page;
DBUG_ENTER("fseg_free_step");
- space_id = page_get_space_id(page_align(header));
- header_page = page_get_page_no(page_align(header));
+ const uint32_t space_id = page_get_space_id(page_align(header));
+ const uint32_t header_page = page_get_page_no(page_align(header));
fil_space_t* space = mtr_x_lock_space(space_id, mtr);
buf_block_t* xdes;
@@ -2682,8 +2691,8 @@ fseg_free_step(
if (descr != NULL) {
/* Free the extent held by the segment */
- page = xdes_get_offset(descr);
- fseg_free_extent(inode, iblock, space, page, mtr);
+ fseg_free_extent(inode, iblock, space, xdes_get_offset(descr),
+ mtr);
DBUG_RETURN(false);
}
@@ -2725,13 +2734,10 @@ fseg_free_step_not_header(
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
- ulint page;
xdes_t* descr;
fseg_inode_t* inode;
- ulint space_id;
- ulint page_no;
- space_id = page_get_space_id(page_align(header));
+ const uint32_t space_id = page_get_space_id(page_align(header));
ut_ad(mtr->is_named_space(space_id));
fil_space_t* space = mtr_x_lock_space(space_id, mtr);
@@ -2747,8 +2753,8 @@ fseg_free_step_not_header(
if (descr != NULL) {
/* Free the extent held by the segment */
- page = xdes_get_offset(descr);
- fseg_free_extent(inode, iblock, space, page, mtr);
+ fseg_free_extent(inode, iblock, space, xdes_get_offset(descr),
+ mtr);
return false;
}
@@ -2758,7 +2764,7 @@ fseg_free_step_not_header(
ut_a(n != ULINT_UNDEFINED);
- page_no = fseg_get_nth_frag_page_no(inode, n);
+ uint32_t page_no = fseg_get_nth_frag_page_no(inode, n);
if (page_no == page_get_page_no(page_align(header))) {
return true;
diff --git a/storage/innobase/fsp/fsp0space.cc b/storage/innobase/fsp/fsp0space.cc
index 1ed4af86367..b0a80efe7c4 100644
--- a/storage/innobase/fsp/fsp0space.cc
+++ b/storage/innobase/fsp/fsp0space.cc
@@ -130,7 +130,7 @@ Tablespace::open_or_create(bool is_temp)
fsp_flags = FSP_FLAGS_PAGE_SSIZE();
}
- space = fil_space_create(
+ space = fil_space_t::create(
m_name, m_space_id, fsp_flags,
is_temp
? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE,
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index 5d381fca033..a2c9e1bc688 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -47,7 +47,7 @@ SysTablespace srv_tmp_space;
/** If the last data file is auto-extended, we add this many pages to it
at a time. We have to make this public because it is a config variable. */
-ulong sys_tablespace_auto_extend_increment;
+uint sys_tablespace_auto_extend_increment;
/** Convert a numeric string that optionally ends in G or M or K,
to a number containing megabytes.
@@ -275,7 +275,8 @@ SysTablespace::parse_params(
}
}
- m_files.push_back(Datafile(filepath, flags(), size, order));
+ m_files.push_back(Datafile(filepath, flags(), uint32_t(size),
+ order));
Datafile* datafile = &m_files.back();
datafile->make_filepath(path(), filepath, NO_EXT);
@@ -351,7 +352,7 @@ SysTablespace::check_size(
also the data file could contain an incomplete extent.
So we need to round the size downward to a megabyte.*/
- const ulint rounded_size_pages = static_cast<ulint>(
+ const uint32_t rounded_size_pages = static_cast<uint32_t>(
size >> srv_page_size_shift);
/* If last file */
@@ -559,7 +560,7 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn)
ut_a(it->order() == 0);
if (srv_operation == SRV_OPERATION_NORMAL) {
- buf_dblwr_init_or_load_pages(it->handle(), it->filepath());
+ buf_dblwr.init_or_load_pages(it->handle(), it->filepath());
}
/* Check the contents of the first page of the
@@ -904,30 +905,22 @@ SysTablespace::open_or_create(
if (it != begin) {
} else if (is_temp) {
- ut_ad(!fil_system.temp_space);
ut_ad(space_id() == SRV_TMP_SPACE_ID);
- space = fil_space_create(
+ space = fil_space_t::create(
name(), SRV_TMP_SPACE_ID, flags(),
FIL_TYPE_TEMPORARY, NULL);
-
- mutex_enter(&fil_system.mutex);
- fil_system.temp_space = space;
- mutex_exit(&fil_system.mutex);
+ ut_ad(space == fil_system.temp_space);
if (!space) {
return DB_ERROR;
}
ut_ad(!space->is_compressed());
ut_ad(space->full_crc32());
} else {
- ut_ad(!fil_system.sys_space);
ut_ad(space_id() == TRX_SYS_SPACE);
- space = fil_space_create(
+ space = fil_space_t::create(
name(), TRX_SYS_SPACE, it->flags(),
FIL_TYPE_TABLESPACE, NULL);
-
- mutex_enter(&fil_system.mutex);
- fil_system.sys_space = space;
- mutex_exit(&fil_system.mutex);
+ ut_ad(space == fil_system.sys_space);
if (!space) {
return DB_ERROR;
}
@@ -935,10 +928,10 @@ SysTablespace::open_or_create(
ut_a(fil_validate());
- ulint max_size = (++node_counter == m_files.size()
+ uint32_t max_size = (++node_counter == m_files.size()
? (m_last_file_size_max == 0
- ? ULINT_MAX
- : m_last_file_size_max)
+ ? UINT32_MAX
+ : uint32_t(m_last_file_size_max))
: it->m_size);
space->add(it->m_filepath, OS_FILE_CLOSED, it->m_size,
@@ -965,30 +958,21 @@ SysTablespace::normalize_size()
/**
@return next increment size */
-ulint
-SysTablespace::get_increment() const
+uint32_t SysTablespace::get_increment() const
{
- ulint increment;
-
- if (m_last_file_size_max == 0) {
- increment = get_autoextend_increment();
- } else {
-
- if (!is_valid_size()) {
- ib::error() << "The last data file in " << name()
- << " has a size of " << last_file_size()
- << " but the max size allowed is "
- << m_last_file_size_max;
- }
-
- increment = m_last_file_size_max - last_file_size();
- }
-
- if (increment > get_autoextend_increment()) {
- increment = get_autoextend_increment();
- }
-
- return(increment);
+ if (m_last_file_size_max == 0)
+ return get_autoextend_increment();
+
+ if (!is_valid_size())
+ {
+ ib::error() << "The last data file in " << name()
+ << " has a size of " << last_file_size()
+ << " but the max size allowed is "
+ << m_last_file_size_max;
+ }
+
+ return std::min(uint32_t(m_last_file_size_max) - last_file_size(),
+ get_autoextend_increment());
}
diff --git a/storage/innobase/fts/fts0ast.cc b/storage/innobase/fts/fts0ast.cc
index a2834f5e7e5..bb42f7c9f54 100644
--- a/storage/innobase/fts/fts0ast.cc
+++ b/storage/innobase/fts/fts0ast.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -557,8 +557,7 @@ fts_ast_node_check_union(
fts_ast_node_t* node)
{
if (node->type == FTS_AST_LIST
- || node->type == FTS_AST_SUBEXP_LIST
- || node->type == FTS_AST_PARSER_PHRASE_LIST) {
+ || node->type == FTS_AST_SUBEXP_LIST) {
for (node = node->list.head; node; node = node->next) {
if (!fts_ast_node_check_union(node)) {
@@ -566,6 +565,9 @@ fts_ast_node_check_union(
}
}
+ } else if (node->type == FTS_AST_PARSER_PHRASE_LIST) {
+ /* Phrase search for plugin parser */
+ return(false);
} else if (node->type == FTS_AST_OPER
&& (node->oper == FTS_IGNORE
|| node->oper == FTS_EXIST)) {
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index b95b77d5d0d..a5945fea791 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -286,7 +286,6 @@ fts_cache_destroy(fts_cache_t* cache)
{
rw_lock_free(&cache->lock);
rw_lock_free(&cache->init_lock);
- mutex_free(&cache->optimize_lock);
mutex_free(&cache->deleted_lock);
mutex_free(&cache->doc_id_lock);
os_event_destroy(cache->sync->event);
@@ -622,8 +621,6 @@ fts_cache_create(
mutex_create(LATCH_ID_FTS_DELETE, &cache->deleted_lock);
- mutex_create(LATCH_ID_FTS_OPTIMIZE, &cache->optimize_lock);
-
mutex_create(LATCH_ID_FTS_DOC_ID, &cache->doc_id_lock);
/* This is the heap used to create the cache itself. */
@@ -5269,7 +5266,6 @@ fts_t::fts_t(
mem_heap_t* heap)
:
added_synced(0), dict_locked(0),
- bg_threads(0),
add_wq(NULL),
cache(NULL),
doc_col(ULINT_UNDEFINED), in_queue(false), sync_message(false),
@@ -5277,8 +5273,6 @@ fts_t::fts_t(
{
ut_a(table->fts == NULL);
- mutex_create(LATCH_ID_FTS_BG_THREADS, &bg_threads_mutex);
-
ib_alloc_t* heap_alloc = ib_heap_allocator_create(fts_heap);
indexes = ib_vector_create(heap_alloc, sizeof(dict_index_t*), 4);
@@ -5289,8 +5283,6 @@ fts_t::fts_t(
/** fts_t destructor. */
fts_t::~fts_t()
{
- mutex_free(&bg_threads_mutex);
-
ut_ad(add_wq == NULL);
if (cache != NULL) {
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 419fc6e0011..b0324bf7667 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -2389,7 +2389,7 @@ fts_optimize_table_bk(
dict_table_t* table = slot->table;
dberr_t error;
- if (fil_table_accessible(table)
+ if (table->is_accessible()
&& table->fts && table->fts->cache
&& table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) {
error = fts_optimize_table(table);
@@ -2590,6 +2590,11 @@ fts_optimize_remove_table(
if (fts_opt_start_shutdown) {
ib::info() << "Try to remove table " << table->name
<< " after FTS optimize thread exiting.";
+ /* If the table can't be removed then wait till
+ fts optimize thread shuts down */
+ while (fts_optimize_wq) {
+ os_thread_sleep(10000);
+ }
return;
}
@@ -2622,9 +2627,13 @@ fts_optimize_remove_table(
os_event_destroy(event);
- ut_d(mutex_enter(&fts_optimize_wq->mutex));
- ut_ad(!table->fts->in_queue);
- ut_d(mutex_exit(&fts_optimize_wq->mutex));
+#ifdef UNIV_DEBUG
+ if (!fts_opt_start_shutdown) {
+ mutex_enter(&fts_optimize_wq->mutex);
+ ut_ad(!table->fts->in_queue);
+ mutex_exit(&fts_optimize_wq->mutex);
+ }
+#endif /* UNIV_DEBUG */
}
/** Send sync fts cache for the table.
@@ -2790,8 +2799,7 @@ static void fts_optimize_sync_table(dict_table_t *table,
if (!sync_table)
return;
- if (sync_table->fts && sync_table->fts->cache &&
- fil_table_accessible(sync_table))
+ if (sync_table->fts && sync_table->fts->cache && sync_table->is_accessible())
{
fts_sync_table(sync_table, false);
if (process_message)
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 4baba419ff7..8e2cb838e5a 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
+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
@@ -144,6 +144,8 @@ struct fts_query_t {
ib_rbt_t* wildcard_words; /*!< words with wildcard */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
st_mysql_ftparser* parser; /*!< fts plugin parser */
};
@@ -2964,6 +2966,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
@@ -3088,6 +3092,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 */
@@ -3110,6 +3122,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;
@@ -4410,24 +4423,27 @@ fts_phrase_or_proximity_search(
if (k == ib_vector_size(query->match_array[j])) {
end_list = TRUE;
- if (match[j]->doc_id != match[0]->doc_id) {
- /* no match */
- if (query->flags & FTS_PHRASE) {
- ulint s;
+ if (query->flags & FTS_PHRASE) {
+ ulint s;
+ /* Since i is the last doc id in the
+ match_array[j], remove all doc ids > i
+ from the match_array[0]. */
+ fts_match_t* match_temp;
+ for (s = i + 1; s < n_matched; s++) {
+ match_temp = static_cast<
+ fts_match_t*>(ib_vector_get(
+ query->match_array[0], s));
+ match_temp->doc_id = 0;
+ }
+ if (match[j]->doc_id !=
+ match[0]->doc_id) {
+ /* no match */
match[0]->doc_id = 0;
-
- for (s = i + 1; s < n_matched;
- s++) {
- match[0] = static_cast<
- fts_match_t*>(
- ib_vector_get(
- query->match_array[0],
- s));
- match[0]->doc_id = 0;
- }
}
+ }
+ if (match[j]->doc_id != match[0]->doc_id) {
goto func_exit;
}
}
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 21783a94e9c..d9a0ae80c33 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -1237,6 +1237,24 @@ rtr_check_discard_page(
lock_mutex_exit();
}
+/** Structure acts as functor to get the optimistic access of the page.
+It returns true if it successfully gets the page. */
+struct optimistic_get
+{
+ btr_pcur_t *const r_cursor;
+ mtr_t *const mtr;
+
+ optimistic_get(btr_pcur_t *r_cursor,mtr_t *mtr)
+ :r_cursor(r_cursor), mtr(mtr) {}
+
+ bool operator()(buf_block_t *hint) const
+ {
+ return hint && buf_page_optimistic_get(
+ RW_X_LATCH, hint, r_cursor->modify_clock, __FILE__,
+ __LINE__, mtr);
+ }
+};
+
/** Restore the stored position of a persistent cursor bufferfixing the page */
static
bool
@@ -1270,11 +1288,8 @@ rtr_cur_restore_position(
ut_ad(latch_mode == BTR_CONT_MODIFY_TREE);
- if (!buf_pool.is_obsolete(r_cursor->withdraw_clock)
- && buf_page_optimistic_get(RW_X_LATCH,
- r_cursor->block_when_stored,
- r_cursor->modify_clock,
- __FILE__, __LINE__, mtr)) {
+ if (r_cursor->block_when_stored.run_with_hint(
+ optimistic_get(r_cursor, mtr))) {
ut_ad(r_cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
@@ -1323,8 +1338,8 @@ rtr_cur_restore_position(
page_cur_t* page_cursor;
node_visit_t* node = rtr_get_parent_node(btr_cur, level, false);
node_seq_t path_ssn = node->seq_no;
- const ulint zip_size = index->table->space->zip_size();
- ulint page_no = node->page_no;
+ const unsigned zip_size = index->table->space->zip_size();
+ uint32_t page_no = node->page_no;
heap = mem_heap_create(256);
@@ -1484,14 +1499,13 @@ rtr_non_leaf_insert_stack_push(
dict_index_t* index, /*!< in: index descriptor */
rtr_node_path_t* path, /*!< in/out: search path */
ulint level, /*!< in: index page level */
- ulint child_no,/*!< in: child page no */
+ uint32_t child_no,/*!< in: child page no */
const buf_block_t* block, /*!< in: block of the page */
const rec_t* rec, /*!< in: positioned record */
double mbr_inc)/*!< in: MBR needs to be enlarged */
{
node_seq_t new_seq;
btr_pcur_t* my_cursor;
- ulint page_no = block->page.id().page_no();
my_cursor = static_cast<btr_pcur_t*>(
ut_malloc_nokey(sizeof(*my_cursor)));
@@ -1503,8 +1517,8 @@ rtr_non_leaf_insert_stack_push(
(btr_pcur_get_btr_cur(my_cursor))->index = index;
new_seq = rtr_get_current_ssn_id(index);
- rtr_non_leaf_stack_push(path, page_no, new_seq, level, child_no,
- my_cursor, mbr_inc);
+ rtr_non_leaf_stack_push(path, block->page.id().page_no(),
+ new_seq, level, child_no, my_cursor, mbr_inc);
}
/** Copy a buf_block_t, except "block->lock".
@@ -1827,7 +1841,7 @@ rtr_cur_search_with_match(
rtr_info->matches for leaf nodes */
if (rtr_info && mode != PAGE_CUR_RTREE_INSERT) {
if (!is_leaf) {
- ulint page_no;
+ uint32_t page_no;
node_seq_t new_seq;
bool is_loc;
@@ -1919,12 +1933,11 @@ rtr_cur_search_with_match(
then we select the record that result in
least increased area */
if (mode == PAGE_CUR_RTREE_INSERT) {
- ulint child_no;
ut_ad(least_inc < DBL_MAX);
offsets = rec_get_offsets(
best_rec, index, offsets,
false, ULINT_UNDEFINED, &heap);
- child_no =
+ uint32_t child_no =
btr_node_ptr_get_child_page_no(
best_rec, offsets);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 400b595dd03..cff12b9bdee 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -223,6 +223,27 @@ enum default_row_format_enum {
DEFAULT_ROW_FORMAT_DYNAMIC = 2,
};
+/** A dummy variable */
+static uint innodb_max_purge_lag_wait;
+
+/** Wait for trx_sys_t::rseg_history_len to be below a limit. */
+static void innodb_max_purge_lag_wait_update(THD *thd, st_mysql_sys_var *,
+ void *, const void *limit)
+{
+ const uint l= *static_cast<const uint*>(limit);
+ if (trx_sys.rseg_history_len <= l)
+ return;
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ while (trx_sys.rseg_history_len > l)
+ {
+ if (thd_kill_level(thd))
+ break;
+ srv_wake_purge_thread_if_not_active();
+ os_thread_sleep(100000);
+ }
+ mysql_mutex_lock(&LOCK_global_system_variables);
+}
+
static
void set_my_errno(int err)
{
@@ -493,48 +514,37 @@ performance schema instrumented if "UNIV_PFS_MUTEX"
is defined */
static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(buf_pool_mutex),
- PSI_KEY(cache_last_read_mutex),
PSI_KEY(dict_foreign_err_mutex),
PSI_KEY(dict_sys_mutex),
PSI_KEY(recalc_pool_mutex),
PSI_KEY(fil_system_mutex),
PSI_KEY(flush_list_mutex),
- PSI_KEY(fts_bg_threads_mutex),
PSI_KEY(fts_delete_mutex),
- PSI_KEY(fts_optimize_mutex),
PSI_KEY(fts_doc_id_mutex),
PSI_KEY(log_flush_order_mutex),
PSI_KEY(ibuf_bitmap_mutex),
PSI_KEY(ibuf_mutex),
PSI_KEY(ibuf_pessimistic_insert_mutex),
PSI_KEY(log_sys_mutex),
- PSI_KEY(log_sys_write_mutex),
- PSI_KEY(mutex_list_mutex),
PSI_KEY(page_zip_stat_per_index_mutex),
PSI_KEY(purge_sys_pq_mutex),
PSI_KEY(recv_sys_mutex),
- PSI_KEY(recv_writer_mutex),
PSI_KEY(redo_rseg_mutex),
PSI_KEY(noredo_rseg_mutex),
# ifdef UNIV_DEBUG
PSI_KEY(rw_lock_debug_mutex),
# endif /* UNIV_DEBUG */
PSI_KEY(rw_lock_list_mutex),
- PSI_KEY(rw_lock_mutex),
PSI_KEY(srv_innodb_monitor_mutex),
PSI_KEY(srv_misc_tmpfile_mutex),
PSI_KEY(srv_monitor_file_mutex),
PSI_KEY(buf_dblwr_mutex),
PSI_KEY(trx_pool_mutex),
PSI_KEY(trx_pool_manager_mutex),
- PSI_KEY(srv_sys_mutex),
PSI_KEY(lock_mutex),
PSI_KEY(lock_wait_mutex),
PSI_KEY(trx_mutex),
PSI_KEY(srv_threads_mutex),
-# ifndef PFS_SKIP_EVENT_MUTEX
- PSI_KEY(event_mutex),
-# endif /* PFS_SKIP_EVENT_MUTEX */
PSI_KEY(rtr_active_mutex),
PSI_KEY(rtr_match_mutex),
PSI_KEY(rtr_path_mutex),
@@ -562,7 +572,6 @@ static PSI_rwlock_info all_innodb_rwlocks[] = {
PSI_RWLOCK_KEY(trx_purge_latch),
PSI_RWLOCK_KEY(index_tree_rw_lock),
PSI_RWLOCK_KEY(index_online_log),
- PSI_RWLOCK_KEY(dict_table_stats)
};
# endif /* UNIV_PFS_RWLOCK */
@@ -572,7 +581,6 @@ performance schema instrumented if "UNIV_PFS_THREAD"
is defined */
static PSI_thread_info all_innodb_threads[] = {
PSI_KEY(page_cleaner_thread),
- PSI_KEY(recv_writer_thread),
PSI_KEY(trx_rollback_clean_thread),
PSI_KEY(thread_pool_thread)
};
@@ -873,8 +881,7 @@ static SHOW_VAR innodb_status_variables[]= {
&export_vars.innodb_buffer_pool_pages_dirty, SHOW_SIZE_T},
{"buffer_pool_bytes_dirty",
&export_vars.innodb_buffer_pool_bytes_dirty, SHOW_SIZE_T},
- {"buffer_pool_pages_flushed",
- &export_vars.innodb_buffer_pool_pages_flushed, SHOW_SIZE_T},
+ {"buffer_pool_pages_flushed", &buf_flush_page_count, SHOW_SIZE_T},
{"buffer_pool_pages_free",
&export_vars.innodb_buffer_pool_pages_free, SHOW_SIZE_T},
#ifdef UNIV_DEBUG
@@ -974,7 +981,7 @@ static SHOW_VAR innodb_status_variables[]= {
{"system_rows_read", &export_vars.innodb_system_rows_read, SHOW_SIZE_T},
{"system_rows_updated", &export_vars.innodb_system_rows_updated,
SHOW_SIZE_T},
- {"num_open_files", &export_vars.innodb_num_open_files, SHOW_SIZE_T},
+ {"num_open_files", &fil_system.n_open, SHOW_SIZE_T},
{"truncated_status_writes", &export_vars.innodb_truncated_status_writes,
SHOW_SIZE_T},
{"available_undo_logs", &srv_available_undo_logs, SHOW_ULONG},
@@ -2259,6 +2266,12 @@ innobase_trx_init(
DBUG_ENTER("innobase_trx_init");
DBUG_ASSERT(thd == trx->mysql_thd);
+ /* Ensure that thd_lock_wait_timeout(), which may be called
+ while holding lock_sys.mutex, by lock_rec_enqueue_waiting(),
+ will not end up acquiring LOCK_global_system_variables in
+ intern_sys_var_ptr(). */
+ THDVAR(thd, lock_wait_timeout);
+
trx->check_foreigns = !thd_test_options(
thd, OPTION_NO_FOREIGN_KEY_CHECKS);
@@ -13924,6 +13937,8 @@ ha_innobase::info_low(
DEBUG_SYNC_C("ha_innobase_info_low");
+ ut_ad(!mutex_own(&dict_sys.mutex));
+
/* If we are forcing recovery at a high level, we will suppress
statistics calculation on tables, because that may crash the
server if an index is badly corrupted. */
@@ -13960,7 +13975,6 @@ ha_innobase::info_low(
opt = DICT_STATS_RECALC_TRANSIENT;
}
- ut_ad(!mutex_own(&dict_sys.mutex));
ret = dict_stats_update(ib_table, opt);
if (ret != DB_SUCCESS) {
@@ -13976,14 +13990,14 @@ ha_innobase::info_low(
stats.update_time = (ulong) ib_table->update_time;
}
+ DBUG_EXECUTE_IF("dict_sys_mutex_avoid", goto func_exit;);
+
if (flag & HA_STATUS_VARIABLE) {
ulint stat_clustered_index_size;
ulint stat_sum_of_other_index_sizes;
- if (!(flag & HA_STATUS_NO_LOCK)) {
- rw_lock_s_lock(&ib_table->stats_latch);
- }
+ mutex_enter(&dict_sys.mutex);
ut_a(ib_table->stat_initialized);
@@ -13995,9 +14009,7 @@ ha_innobase::info_low(
stat_sum_of_other_index_sizes
= ib_table->stat_sum_of_other_index_sizes;
- if (!(flag & HA_STATUS_NO_LOCK)) {
- rw_lock_s_unlock(&ib_table->stats_latch);
- }
+ mutex_exit(&dict_sys.mutex);
/*
The MySQL optimizer seems to assume in a left join that n_rows
@@ -14098,10 +14110,26 @@ ha_innobase::info_low(
ib_push_frm_error(m_user_thd, ib_table, table, num_innodb_index, true);
}
- if (!(flag & HA_STATUS_NO_LOCK)) {
- rw_lock_s_lock(&ib_table->stats_latch);
+ snprintf(path, sizeof(path), "%s/%s%s",
+ mysql_data_home, table->s->normalized_path.str,
+ reg_ext);
+
+ unpack_filename(path,path);
+
+ /* Note that we do not know the access time of the table,
+ nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
+
+ if (os_file_get_status(
+ path, &stat_info, false,
+ srv_read_only_mode) == DB_SUCCESS) {
+ stats.create_time = (ulong) stat_info.ctime;
}
+ struct Locking {
+ Locking() { mutex_enter(&dict_sys.mutex); }
+ ~Locking() { mutex_exit(&dict_sys.mutex); }
+ } locking;
+
ut_a(ib_table->stat_initialized);
for (uint i = 0; i < table->s->keys; i++) {
@@ -14179,25 +14207,6 @@ ha_innobase::info_low(
key->rec_per_key[j] = rec_per_key_int;
}
}
-
- if (!(flag & HA_STATUS_NO_LOCK)) {
- rw_lock_s_unlock(&ib_table->stats_latch);
- }
-
- snprintf(path, sizeof(path), "%s/%s%s",
- mysql_data_home, table->s->normalized_path.str,
- reg_ext);
-
- unpack_filename(path,path);
-
- /* Note that we do not know the access time of the table,
- nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
-
- if (os_file_get_status(
- path, &stat_info, false,
- srv_read_only_mode) == DB_SUCCESS) {
- stats.create_time = (ulong) stat_info.ctime;
- }
}
if (srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE) {
@@ -14271,25 +14280,14 @@ ha_innobase::analyze(THD*, HA_CHECK_OPT*)
/*****************************************************************//**
Defragment table.
@return error number */
-UNIV_INTERN
-int
-ha_innobase::defragment_table(
-/*==========================*/
- const char* name, /*!< in: table name */
- const char* index_name, /*!< in: index name */
- bool async) /*!< in: whether to wait until finish */
+inline int ha_innobase::defragment_table(const char *name)
{
char norm_name[FN_REFLEN];
dict_table_t* table = NULL;
dict_index_t* index = NULL;
- ibool one_index = (index_name != 0);
int ret = 0;
dberr_t err = DB_SUCCESS;
- if (!srv_defragment) {
- return ER_FEATURE_DISABLED;
- }
-
normalize_table_name(norm_name, name);
table = dict_table_open_on_name(norm_name, FALSE,
@@ -14317,10 +14315,6 @@ ha_innobase::defragment_table(
continue;
}
- if (one_index && strcasecmp(index_name, index->name) != 0) {
- continue;
- }
-
if (btr_defragment_find_index(index)) {
// We borrow this error code. When the same index is
// already in the defragmentation queue, issue another
@@ -14336,7 +14330,7 @@ ha_innobase::defragment_table(
break;
}
- os_event_t event = btr_defragment_add_index(index, async, &err);
+ os_event_t event = btr_defragment_add_index(index, &err);
if (err != DB_SUCCESS) {
push_warning_printf(
@@ -14352,7 +14346,7 @@ ha_innobase::defragment_table(
break;
}
- if (!async && event) {
+ if (event) {
while(os_event_wait_time(event, 1000000)) {
if (thd_killed(current_thd)) {
btr_defragment_remove_index(index);
@@ -14366,19 +14360,9 @@ ha_innobase::defragment_table(
if (ret) {
break;
}
-
- if (one_index) {
- one_index = FALSE;
- break;
- }
}
dict_table_close(table, FALSE, FALSE);
-
- if (ret == 0 && one_index) {
- ret = ER_NO_SUCH_INDEX;
- }
-
return ret;
}
@@ -14404,8 +14388,7 @@ ha_innobase::optimize(
bool try_alter = true;
if (!m_prebuilt->table->is_temporary() && srv_defragment) {
- int err= defragment_table(
- m_prebuilt->table->name.m_name, NULL, false);
+ int err = defragment_table(m_prebuilt->table->name.m_name);
if (err == 0) {
try_alter = false;
@@ -15748,8 +15731,7 @@ struct ShowStatus {
/** Collect the latch metrics. Ignore entries where the
spins and waits are zero.
@param[in] count The latch metrics */
- void operator()(Count* count)
- UNIV_NOTHROW
+ void operator()(Count* count) const UNIV_NOTHROW
{
if (count->m_spins > 0 || count->m_waits > 0) {
@@ -15777,13 +15759,8 @@ struct ShowStatus {
bool operator()(latch_meta_t& latch_meta)
UNIV_NOTHROW
{
- latch_meta_t::CounterType* counter;
-
- counter = latch_meta.get_counter();
-
- GetCount get_count(latch_meta.get_name(), &m_values);
-
- counter->iterate(get_count);
+ latch_meta.get_counter()->iterate(
+ GetCount(latch_meta.get_name(), &m_values));
return(true);
}
@@ -17239,20 +17216,8 @@ innodb_change_buffer_max_size_update(THD*, st_mysql_sys_var*, void*,
}
#ifdef UNIV_DEBUG
-static ulong srv_fil_make_page_dirty_debug = 0;
-static ulong srv_saved_page_number_debug = 0;
-
-/****************************************************************//**
-Save an InnoDB page number. */
-static
-void
-innodb_save_page_no(THD*, st_mysql_sys_var*, void*, const void* save)
-{
- srv_saved_page_number_debug = *static_cast<const ulong*>(save);
-
- ib::info() << "Saving InnoDB page number: "
- << srv_saved_page_number_debug;
-}
+static uint srv_fil_make_page_dirty_debug = 0;
+static uint srv_saved_page_number_debug;
/****************************************************************//**
Make the first page of given user tablespace dirty. */
@@ -17261,9 +17226,9 @@ void
innodb_make_page_dirty(THD*, st_mysql_sys_var*, void*, const void* save)
{
mtr_t mtr;
- ulong space_id = *static_cast<const ulong*>(save);
+ uint space_id = *static_cast<const uint*>(save);
mysql_mutex_unlock(&LOCK_global_system_variables);
- fil_space_t* space = fil_space_acquire_silent(space_id);
+ fil_space_t* space = fil_space_t::get(space_id);
if (space == NULL) {
func_exit_no_space:
@@ -17291,6 +17256,7 @@ func_exit:
block->frame[FIL_PAGE_SPACE_ID]);
}
mtr.commit();
+ log_write_up_to(mtr.commit_lsn(), true);
goto func_exit;
}
#endif // UNIV_DEBUG
@@ -17752,7 +17718,7 @@ static bool innodb_buffer_pool_evict_uncompressed()
{
bool all_evicted = true;
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
for (buf_block_t* block = UT_LIST_GET_LAST(buf_pool.unzip_LRU);
block != NULL; ) {
@@ -17772,7 +17738,7 @@ static bool innodb_buffer_pool_evict_uncompressed()
}
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
return(all_evicted);
}
@@ -18729,7 +18695,7 @@ static MYSQL_SYSVAR_STR(log_group_home_dir, srv_log_group_home_dir,
static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, innodb_max_dirty_pages_pct_update, 75.0, 0, 99.999, 0);
+ NULL, innodb_max_dirty_pages_pct_update, 90.0, 0, 99.999, 0);
static MYSQL_SYSVAR_DOUBLE(max_dirty_pages_pct_lwm,
srv_max_dirty_pages_pct_lwm,
@@ -18772,6 +18738,11 @@ static MYSQL_SYSVAR_ULONG(max_purge_lag_delay, srv_max_purge_lag_delay,
0L, /* Minimum value */
10000000UL, 0); /* Maximum value */
+static MYSQL_SYSVAR_UINT(max_purge_lag_wait, innodb_max_purge_lag_wait,
+ PLUGIN_VAR_RQCMDARG,
+ "Wait until History list length is below the specified limit",
+ NULL, innodb_max_purge_lag_wait_update, UINT_MAX, 0, UINT_MAX, 0);
+
static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
"Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
@@ -18847,11 +18818,11 @@ static MYSQL_SYSVAR_UINT(compression_level, page_zip_level,
", 1 is fastest, 9 is best compression and default is 6.",
NULL, NULL, DEFAULT_COMPRESSION_LEVEL, 0, 9, 0);
-static MYSQL_SYSVAR_ULONG(autoextend_increment,
+static MYSQL_SYSVAR_UINT(autoextend_increment,
sys_tablespace_auto_extend_increment,
PLUGIN_VAR_RQCMDARG,
"Data file autoextend increment in megabytes",
- NULL, NULL, 64L, 1L, 1000L, 0);
+ NULL, NULL, 64, 1, 1000, 0);
/** Validate the requested buffer pool size. Also, reserve the necessary
memory needed for buffer pool resize.
@@ -18886,13 +18857,6 @@ static MYSQL_SYSVAR_ULONG(buffer_pool_chunk_size, srv_buf_pool_chunk_unit,
NULL, NULL,
128 * 1024 * 1024, 1024 * 1024, LONG_MAX, 1024 * 1024);
-#if defined UNIV_DEBUG || defined UNIV_PERF_DEBUG
-static MYSQL_SYSVAR_ULONG(doublewrite_batch_size, srv_doublewrite_batch_size,
- PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
- "Number of pages reserved in doublewrite buffer for batch flushing",
- NULL, NULL, 120, 1, 127, 0);
-#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */
-
static MYSQL_SYSVAR_STR(buffer_pool_filename, srv_buf_dump_filename,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Filename to/from which to dump/load the InnoDB buffer pool",
@@ -18999,7 +18963,12 @@ static MYSQL_SYSVAR_UINT(defragment_frequency, srv_defragment_frequency,
static MYSQL_SYSVAR_ULONG(lru_scan_depth, srv_LRU_scan_depth,
PLUGIN_VAR_RQCMDARG,
"How deep to scan LRU to keep it clean",
- NULL, NULL, 1024, 100, ~0UL, 0);
+ NULL, NULL, 1536, 100, ~0UL, 0);
+
+static MYSQL_SYSVAR_SIZE_T(lru_flush_size, innodb_lru_flush_size,
+ PLUGIN_VAR_RQCMDARG,
+ "How many pages to flush on LRU eviction",
+ NULL, NULL, 32, 1, SIZE_T_MAX, 0);
static MYSQL_SYSVAR_ULONG(flush_neighbors, srv_flush_neighbors,
PLUGIN_VAR_OPCMDARG,
@@ -19410,15 +19379,15 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug,
"InnoDB system tablespace size to be set in recovery.",
NULL, NULL, 0, 0, 256U << 20, 0);
-static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug,
+static MYSQL_SYSVAR_UINT(fil_make_page_dirty_debug,
srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG,
"Make the first page of the given tablespace dirty.",
NULL, innodb_make_page_dirty, 0, 0, UINT_MAX32, 0);
-static MYSQL_SYSVAR_ULONG(saved_page_number_debug,
+static MYSQL_SYSVAR_UINT(saved_page_number_debug,
srv_saved_page_number_debug, PLUGIN_VAR_OPCMDARG,
"An InnoDB page number.",
- NULL, innodb_save_page_no, 0, 0, UINT_MAX32, 0);
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
static MYSQL_SYSVAR_BOOL(disable_resize_buffer_pool_debug,
buf_disable_resize_buffer_pool_debug, PLUGIN_VAR_NOCMDARG,
@@ -19563,6 +19532,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(defragment_fill_factor_n_recs),
MYSQL_SYSVAR(defragment_frequency),
MYSQL_SYSVAR(lru_scan_depth),
+ MYSQL_SYSVAR(lru_flush_size),
MYSQL_SYSVAR(flush_neighbors),
MYSQL_SYSVAR(checksum_algorithm),
MYSQL_SYSVAR(compression_level),
@@ -19605,6 +19575,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(flushing_avg_loops),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(max_purge_lag_delay),
+ MYSQL_SYSVAR(max_purge_lag_wait),
MYSQL_SYSVAR(old_blocks_pct),
MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
@@ -19670,9 +19641,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(buf_flush_list_now),
MYSQL_SYSVAR(merge_threshold_set_all_debug),
#endif /* UNIV_DEBUG */
-#if defined UNIV_DEBUG || defined UNIV_PERF_DEBUG
- MYSQL_SYSVAR(doublewrite_batch_size),
-#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */
MYSQL_SYSVAR(status_output),
MYSQL_SYSVAR(status_output_locks),
MYSQL_SYSVAR(print_all_deadlocks),
@@ -20733,10 +20701,10 @@ innodb_buffer_pool_size_validate(
#endif /* UNIV_DEBUG */
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
if (srv_buf_pool_old_size != srv_buf_pool_size) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
my_printf_error(ER_WRONG_ARGUMENTS,
"Another buffer pool resize is already in progress.", MYF(0));
return(1);
@@ -20747,13 +20715,13 @@ innodb_buffer_pool_size_validate(
*static_cast<ulonglong*>(save) = requested_buf_pool_size;
if (srv_buf_pool_size == ulint(intbuf)) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
/* nothing to do */
return(0);
}
if (srv_buf_pool_size == requested_buf_pool_size) {
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"innodb_buffer_pool_size must be at least"
@@ -20764,7 +20732,7 @@ innodb_buffer_pool_size_validate(
}
srv_buf_pool_size = requested_buf_pool_size;
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
if (intbuf != static_cast<longlong>(requested_buf_pool_size)) {
char buf[64];
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index c8efcf84af9..3938fe2de93 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -212,8 +212,7 @@ public:
int delete_table(const char *name) override;
int rename_table(const char* from, const char* to) override;
- int defragment_table(const char* name, const char* index_name,
- bool async);
+ inline int defragment_table(const char* name);
int check(THD* thd, HA_CHECK_OPT* check_opt) override;
char* update_table_comment(const char* comment) override;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index f80ee865746..7d20796b646 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -56,6 +56,8 @@ Smart ALTER TABLE
#include "ha_innodb.h"
#include "ut0stage.h"
#include "span.h"
+#include <thread>
+#include <sstream>
using st_::span;
/** File format constraint for ALTER TABLE */
@@ -553,8 +555,11 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
mem_heap_dup(heap, table.v_col_names,
ulint(end - table.v_col_names)));
v_cols = static_cast<dict_v_col_t*>(
- mem_heap_dup(heap, table.v_cols,
- table.n_v_cols * sizeof *v_cols));
+ mem_heap_alloc(heap, table.n_v_cols * sizeof(*v_cols)));
+ for (ulint i = table.n_v_cols; i--; ) {
+ new (&v_cols[i]) dict_v_col_t(table.v_cols[i]);
+ v_cols[i].v_indexes.clear();
+ }
} else {
ut_ad(table.n_v_cols == 0);
v_col_names = NULL;
@@ -570,7 +575,6 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
for (unsigned i = 0; i < n_v_def; i++) {
dict_v_col_t& v = v_cols[i];
DBUG_ASSERT(v.v_indexes.empty());
- v.n_v_indexes = 0;
v.base_col = static_cast<dict_col_t**>(
mem_heap_dup(heap, v.base_col,
v.num_base * sizeof *v.base_col));
@@ -680,7 +684,6 @@ dup_dropped:
<dict_v_col_t*>(f.col);
v_col->v_indexes.push_front(
dict_v_idx_t(index, i));
- v_col->n_v_indexes++;
}
}
}
@@ -4963,7 +4966,6 @@ prepare_inplace_add_virtual(
- ctx->num_to_drop_vcol + j)
& dict_index_t::MAX_N_FIELDS;
- ctx->add_vcol[j].n_v_indexes = 0;
/* MDEV-17468: Do this on ctx->instant_table later */
innodb_base_col_setup(ctx->old_table, field, &ctx->add_vcol[j]);
j++;
@@ -7167,6 +7169,12 @@ err_exit:
}
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;
@@ -7358,22 +7366,28 @@ innobase_rename_index_cache(dict_index_t* index, const char* new_name)
/** Rename the index name in cache.
@param[in] ctx alter context
@param[in] ha_alter_info Data used during inplace alter. */
-static void innobase_rename_indexes_cache(
- const ha_innobase_inplace_ctx* ctx,
- const Alter_inplace_info* ha_alter_info)
+static void
+innobase_rename_indexes_cache(const ha_innobase_inplace_ctx *ctx,
+ const Alter_inplace_info *ha_alter_info)
{
- DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_RENAME_INDEX);
+ DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_RENAME_INDEX);
- for (const Alter_inplace_info::Rename_key_pair& pair :
- ha_alter_info->rename_keys) {
- dict_index_t* index = dict_table_get_index_on_name(
- ctx->old_table, pair.old_key->name.str);
- ut_ad(index);
+ std::vector<std::pair<dict_index_t *, const char *>> rename_info;
+ rename_info.reserve(ha_alter_info->rename_keys.size());
- innobase_rename_index_cache(index, pair.new_key->name.str);
- }
-}
+ for (const Alter_inplace_info::Rename_key_pair &pair :
+ ha_alter_info->rename_keys)
+ {
+ dict_index_t *index=
+ dict_table_get_index_on_name(ctx->old_table, pair.old_key->name.str);
+ ut_ad(index);
+
+ rename_info.emplace_back(index, pair.new_key->name.str);
+ }
+ for (const auto &pair : rename_info)
+ innobase_rename_index_cache(pair.first, pair.second);
+}
/** Fill the stored column information in s_cols list.
@param[in] altered_table mysql table object
@@ -10310,13 +10324,15 @@ commit_cache_norebuild(
page_id_t(space->id, 0),
space->zip_size(),
RW_X_LATCH, &mtr)) {
- mtr.set_named_space(space);
- mtr.write<4,mtr_t::MAYBE_NOP>(
- *b,
- FSP_HEADER_OFFSET
- + FSP_SPACE_FLAGS + b->frame,
- space->flags
- & ~FSP_FLAGS_MEM_MASK);
+ byte* f = FSP_HEADER_OFFSET
+ + FSP_SPACE_FLAGS + b->frame;
+ const auto sf = space->flags
+ & ~FSP_FLAGS_MEM_MASK;
+ if (mach_read_from_4(f) != sf) {
+ mtr.set_named_space(space);
+ mtr.write<4,mtr_t::FORCED>(
+ *b, f, sf);
+ }
}
mtr.commit();
}
@@ -10528,11 +10544,18 @@ alter_stats_norebuild(
}
}
- for (const Alter_inplace_info::Rename_key_pair& pair :
- ha_alter_info->rename_keys) {
+ for (size_t i = 0; i < ha_alter_info->rename_keys.size(); i++) {
+ const Alter_inplace_info::Rename_key_pair& pair
+ = ha_alter_info->rename_keys[i];
+
+ std::stringstream ss;
+ ss << TEMP_FILE_PREFIX_INNODB << std::this_thread::get_id()
+ << i;
+ auto tmp_name = ss.str();
+
dberr_t err = dict_stats_rename_index(ctx->new_table,
pair.old_key->name.str,
- pair.new_key->name.str);
+ tmp_name.c_str());
if (err != DB_SUCCESS) {
push_warning_printf(
@@ -10544,6 +10567,34 @@ alter_stats_norebuild(
" statistics storage: %s",
ctx->new_table->name.m_name,
pair.old_key->name.str,
+ tmp_name.c_str(),
+ ut_strerr(err));
+ }
+ }
+
+ for (size_t i = 0; i < ha_alter_info->rename_keys.size(); i++) {
+ const Alter_inplace_info::Rename_key_pair& pair
+ = ha_alter_info->rename_keys[i];
+
+ std::stringstream ss;
+ ss << TEMP_FILE_PREFIX_INNODB << std::this_thread::get_id()
+ << i;
+ auto tmp_name = ss.str();
+
+ dberr_t err = dict_stats_rename_index(ctx->new_table,
+ tmp_name.c_str(),
+ pair.new_key->name.str);
+
+ if (err != DB_SUCCESS) {
+ push_warning_printf(
+ thd,
+ Sql_condition::WARN_LEVEL_WARN,
+ ER_ERROR_ON_RENAME,
+ "Error renaming an index of table '%s'"
+ " from '%s' to '%s' in InnoDB persistent"
+ " statistics storage: %s",
+ ctx->new_table->name.m_name,
+ tmp_name.c_str(),
pair.new_key->name.str,
ut_strerr(err));
}
@@ -10797,11 +10848,11 @@ ha_innobase::commit_inplace_alter_table(
/* Exclusively lock the table, to ensure that no other
transaction is holding locks on the table while we
- change the table definition. The meta-data lock (MDL)
+ change the table definition. The MySQL meta-data lock
should normally guarantee that no conflicting locks
exist. However, FOREIGN KEY constraints checks and any
transactions collected during crash recovery could be
- holding InnoDB locks only, not MDL. */
+ holding InnoDB locks only, not MySQL locks. */
dberr_t error = row_merge_lock_table(
m_prebuilt->trx, ctx->old_table, LOCK_X);
@@ -11155,7 +11206,7 @@ foreign_fail:
}
dict_sys.remove(m_prebuilt->table);
m_prebuilt->table = dict_table_open_on_name(
- tb_name, TRUE, TRUE, DICT_ERR_IGNORE_NONE);
+ tb_name, TRUE, TRUE, DICT_ERR_IGNORE_FK_NOKEY);
/* Drop outdated table stats. */
char errstr[1024];
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index a5713e32d86..ecc0905de56 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1635,7 +1635,7 @@ i_s_cmpmem_fill_low(
buf_buddy_stat_t buddy_stat_local[BUF_BUDDY_SIZES_MAX + 1];
/* Save buddy stats for buffer pool in local variables. */
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
zip_free_len_local[x] = (x < BUF_BUDDY_SIZES) ?
@@ -1650,7 +1650,7 @@ i_s_cmpmem_fill_low(
}
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
buf_buddy_stat_t* buddy_stat = &buddy_stat_local[x];
@@ -4270,7 +4270,7 @@ static int i_s_innodb_buffer_page_fill(THD *thd, TABLE_LIST *tables, Item *)
buffer pool info printout, we are not required to
preserve the overall consistency, so we can
release mutex periodically */
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
/* GO through each block in the chunk */
for (n_blocks = num_to_process; n_blocks--; block++) {
@@ -4281,7 +4281,7 @@ static int i_s_innodb_buffer_page_fill(THD *thd, TABLE_LIST *tables, Item *)
num_page++;
}
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
/* Fill in information schema table with information
just collected from the buffer chunk scan */
@@ -4604,7 +4604,7 @@ static int i_s_innodb_fill_buffer_lru(THD *thd, TABLE_LIST *tables, Item *)
/* Aquire the mutex before allocating info_buffer, since
UT_LIST_GET_LEN(buf_pool.LRU) could change */
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
lru_len = UT_LIST_GET_LEN(buf_pool.LRU);
@@ -4636,7 +4636,7 @@ static int i_s_innodb_fill_buffer_lru(THD *thd, TABLE_LIST *tables, Item *)
ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool.LRU));
exit:
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
if (info_buffer) {
status = i_s_innodb_buf_page_lru_fill(
@@ -5037,33 +5037,39 @@ i_s_dict_fill_sys_tablestats(
OK(field_store_string(fields[SYS_TABLESTATS_NAME],
table->name.m_name));
- rw_lock_s_lock(&table->stats_latch);
-
- OK(fields[SYS_TABLESTATS_INIT]->store(table->stat_initialized, true));
+ {
+ struct Locking
+ {
+ Locking() { mutex_enter(&dict_sys.mutex); }
+ ~Locking() { mutex_exit(&dict_sys.mutex); }
+ } locking;
- if (table->stat_initialized) {
- OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows,
+ OK(fields[SYS_TABLESTATS_INIT]->store(table->stat_initialized,
true));
- OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
- table->stat_clustered_index_size, true));
+ if (table->stat_initialized) {
+ OK(fields[SYS_TABLESTATS_NROW]->store(
+ table->stat_n_rows, true));
- OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(
- table->stat_sum_of_other_index_sizes, true));
+ OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
+ table->stat_clustered_index_size, true));
- OK(fields[SYS_TABLESTATS_MODIFIED]->store(
- table->stat_modified_counter, true));
- } else {
- OK(fields[SYS_TABLESTATS_NROW]->store(0, true));
+ OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(
+ table->stat_sum_of_other_index_sizes,
+ true));
- OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(0, true));
+ OK(fields[SYS_TABLESTATS_MODIFIED]->store(
+ table->stat_modified_counter, true));
+ } else {
+ OK(fields[SYS_TABLESTATS_NROW]->store(0, true));
- OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(0, true));
+ OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(0, true));
- OK(fields[SYS_TABLESTATS_MODIFIED]->store(0, true));
- }
+ OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(0, true));
- rw_lock_s_unlock(&table->stats_latch);
+ OK(fields[SYS_TABLESTATS_MODIFIED]->store(0, true));
+ }
+ }
OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, true));
@@ -6551,7 +6557,7 @@ i_s_dict_fill_sys_tablespaces(
memset(&file, 0xff, sizeof(file));
memset(&stat, 0x0, sizeof(stat));
- if (fil_space_t* s = fil_space_acquire_silent(space)) {
+ if (fil_space_t* s = fil_space_t::get(space)) {
const char *filepath = s->chain.start
? s->chain.start->name : NULL;
if (!filepath) {
@@ -7044,11 +7050,13 @@ i_s_tablespaces_encryption_fill_table(
}
mutex_enter(&fil_system.mutex);
+ fil_system.freeze_space_list++;
for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
space; space = UT_LIST_GET_NEXT(space_list, space)) {
if (space->purpose == FIL_TYPE_TABLESPACE
- && space->acquire()) {
+ && !space->is_stopping()) {
+ space->reacquire();
mutex_exit(&fil_system.mutex);
if (int err = i_s_dict_fill_tablespaces_encryption(
thd, space, tables->table)) {
@@ -7060,6 +7068,7 @@ i_s_tablespaces_encryption_fill_table(
}
}
+ fil_system.freeze_space_list--;
mutex_exit(&fil_system.mutex);
DBUG_RETURN(0);
}
@@ -7177,32 +7186,7 @@ i_s_innodb_mutexes_fill_table(
/* deny access to user without PROCESS_ACL privilege */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
- }
-
- // mutex_enter(&mutex_list_mutex);
-
-#ifdef JAN_TODO_FIXME
- ib_mutex_t* mutex;
- for (mutex = UT_LIST_GET_FIRST(os_mutex_list); mutex != NULL;
- mutex = UT_LIST_GET_NEXT(list, mutex)) {
- if (mutex->count_os_wait == 0) {
- continue;
- }
-
- OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name));
- OK(field_store_string(fields[MUTEXES_CREATE_FILE],
- innobase_basename(mutex->cfile_name)));
- OK(fields[MUTEXES_CREATE_LINE]->store(lock->cline, true));
- fields[MUTEXES_CREATE_LINE]->set_notnull();
- OK(fields[MUTEXES_OS_WAITS]->store(lock->count_os_wait, true));
- fields[MUTEXES_OS_WAITS]->set_notnull();
- OK(schema_table_store_record(thd, tables->table));
- }
-
- mutex_exit(&mutex_list_mutex);
-#endif /* JAN_TODO_FIXME */
-
- {
+ } else {
struct Locking
{
Locking() { mutex_enter(&rw_lock_list_mutex); }
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index ca13e2e33af..91a450b0711 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -662,10 +662,11 @@ ibuf_bitmap_page_set_bits(
@return the bitmap page id where the file page is mapped */
inline page_id_t ibuf_bitmap_page_no_calc(const page_id_t page_id, ulint size)
{
- if (!size) size = srv_page_size;
+ if (!size)
+ size= srv_page_size;
- return page_id_t(page_id.space(), FSP_IBUF_BITMAP_OFFSET
- + (page_id.page_no() & ~(size - 1)));
+ return page_id_t(page_id.space(), FSP_IBUF_BITMAP_OFFSET
+ + uint32_t(page_id.page_no() & ~(size - 1)));
}
/** Gets the ibuf bitmap page where the bits describing a given file page are
@@ -934,8 +935,7 @@ ibuf_update_free_bits_for_two_pages_low(
@return TRUE if a fixed address ibuf i/o page */
inline bool ibuf_fixed_addr_page(const page_id_t page_id, ulint zip_size)
{
- return((page_id.space() == IBUF_SPACE_ID
- && page_id.page_no() == IBUF_TREE_ROOT_PAGE_NO)
+ return(page_id == page_id_t(IBUF_SPACE_ID, IBUF_TREE_ROOT_PAGE_NO)
|| ibuf_bitmap_page(page_id, zip_size));
}
@@ -1035,7 +1035,7 @@ ibuf_page_low(
Returns the page number field of an ibuf record.
@return page number */
static
-ulint
+uint32_t
ibuf_rec_get_page_no_func(
/*======================*/
#ifdef UNIV_DEBUG
@@ -1073,7 +1073,7 @@ Returns the space id field of an ibuf record. For < 4.1.x format records
returns 0.
@return space id */
static
-ulint
+uint32_t
ibuf_rec_get_space_func(
/*====================*/
#ifdef UNIV_DEBUG
@@ -1309,7 +1309,7 @@ ibuf_dummy_index_create(
dict_index_t* index;
table = dict_mem_table_create("IBUF_DUMMY", NULL, n, 0,
- comp ? DICT_TF_COMPACT : 0, 0, false);
+ comp ? DICT_TF_COMPACT : 0, 0);
index = dict_mem_index_create(table, "IBUF_DUMMY", 0, n);
@@ -1901,7 +1901,6 @@ ibuf_remove_free_page(void)
mtr_t mtr;
mtr_t mtr2;
page_t* header_page;
- ulint page_no;
log_free_check();
@@ -1933,8 +1932,8 @@ ibuf_remove_free_page(void)
mutex_exit(&ibuf_mutex);
- page_no = flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
- + root->frame).page;
+ uint32_t page_no = flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
+ + root->frame).page;
/* NOTE that we must release the latch on the ibuf tree root
because in fseg_free_page we access level 1 pages, and the root
@@ -2043,19 +2042,19 @@ ibuf_get_merge_page_nos_func(
#ifdef UNIV_DEBUG
mtr_t* mtr, /*!< in: mini-transaction holding rec */
#endif /* UNIV_DEBUG */
- ulint* space_ids,/*!< in/out: space id's of the pages */
- ulint* page_nos,/*!< in/out: buffer for at least
+ uint32_t* space_ids,/*!< in/out: space id's of the pages */
+ uint32_t* page_nos,/*!< in/out: buffer for at least
IBUF_MAX_N_PAGES_MERGED many page numbers;
the page numbers are in an ascending order */
ulint* n_stored)/*!< out: number of page numbers stored to
page_nos in this function */
{
- ulint prev_page_no;
- ulint prev_space_id;
- ulint first_page_no;
- ulint first_space_id;
- ulint rec_page_no;
- ulint rec_space_id;
+ uint32_t prev_page_no;
+ uint32_t prev_space_id;
+ uint32_t first_page_no;
+ uint32_t first_space_id;
+ uint32_t rec_page_no;
+ uint32_t rec_space_id;
ulint sum_volumes;
ulint volume_for_page;
ulint rec_volume;
@@ -2248,25 +2247,23 @@ ulint
ibuf_get_merge_pages(
/*=================*/
btr_pcur_t* pcur, /*!< in/out: cursor */
- ulint space, /*!< in: space for which to merge */
+ uint32_t space, /*!< in: space for which to merge */
ulint limit, /*!< in: max page numbers to read */
- ulint* pages, /*!< out: pages read */
- ulint* spaces, /*!< out: spaces read */
+ uint32_t* pages, /*!< out: pages read */
+ uint32_t* spaces, /*!< out: spaces read */
ulint* n_pages,/*!< out: number of pages read */
mtr_t* mtr) /*!< in: mini transaction */
{
const rec_t* rec;
ulint volume = 0;
- ut_a(space != ULINT_UNDEFINED);
-
*n_pages = 0;
while ((rec = ibuf_get_user_rec(pcur, mtr)) != 0
&& ibuf_rec_get_space(mtr, rec) == space
&& *n_pages < limit) {
- ulint page_no = ibuf_rec_get_page_no(mtr, rec);
+ uint32_t page_no = ibuf_rec_get_page_no(mtr, rec);
if (*n_pages == 0 || pages[*n_pages - 1] != page_no) {
spaces[*n_pages] = space;
@@ -2284,19 +2281,18 @@ ibuf_get_merge_pages(
/**
Delete a change buffer record.
-@param[in] space tablespace identifier
-@param[in] page_no page number
+@param[in] page_id page identifier
@param[in,out] pcur persistent cursor positioned on the record
@param[in] search_tuple search key for (space,page_no)
@param[in,out] mtr mini-transaction
@return whether mtr was committed (due to pessimistic operation) */
static MY_ATTRIBUTE((warn_unused_result, nonnull))
-bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
+bool ibuf_delete_rec(const page_id_t page_id, btr_pcur_t* pcur,
const dtuple_t* search_tuple, mtr_t* mtr);
/** Merge the change buffer to some pages. */
-static void ibuf_read_merge_pages(const ulint* space_ids,
- const ulint* page_nos, ulint n_stored)
+static void ibuf_read_merge_pages(const uint32_t* space_ids,
+ const uint32_t* page_nos, ulint n_stored)
{
mem_heap_t* heap = mem_heap_create(512);
ulint dops[IBUF_OP_COUNT];
@@ -2304,7 +2300,7 @@ static void ibuf_read_merge_pages(const ulint* space_ids,
for (ulint i = 0; i < n_stored; i++) {
const ulint space_id = space_ids[i];
- fil_space_t* s = fil_space_acquire_for_io(space_id);
+ fil_space_t* s = fil_space_t::get(space_id);
if (!s) {
tablespace_deleted:
/* The tablespace was not found: remove all
@@ -2318,7 +2314,7 @@ tablespace_deleted:
}
const ulint zip_size = s->zip_size(), size = s->size;
- s->release_for_io();
+ s->release();
mtr_t mtr;
if (UNIV_LIKELY(page_nos[i] < size)) {
@@ -2360,7 +2356,7 @@ loop:
dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
/* Delete the record from ibuf */
- if (ibuf_delete_rec(space_id, page_nos[i],
+ if (ibuf_delete_rec(page_id_t(space_id, page_nos[i]),
&pcur, tuple, &mtr)) {
/* Deletion was pessimistic and mtr
was committed: we start from the
@@ -2399,8 +2395,8 @@ ibuf_merge_pages(
mtr_t mtr;
btr_pcur_t pcur;
ulint sum_sizes;
- ulint page_nos[IBUF_MAX_N_PAGES_MERGED];
- ulint space_ids[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t page_nos[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t space_ids[IBUF_MAX_N_PAGES_MERGED];
*n_pages = 0;
@@ -2473,8 +2469,8 @@ ibuf_merge_space(
ut_ad(page_validate(btr_pcur_get_page(&pcur), ibuf.index));
ulint sum_sizes = 0;
- ulint pages[IBUF_MAX_N_PAGES_MERGED];
- ulint spaces[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t pages[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t spaces[IBUF_MAX_N_PAGES_MERGED];
if (page_is_empty(btr_pcur_get_page(&pcur))) {
/* If a B-tree page is empty, it must be the root page
@@ -2486,7 +2482,7 @@ ibuf_merge_space(
} else {
sum_sizes = ibuf_get_merge_pages(
- &pcur, space, IBUF_MAX_N_PAGES_MERGED,
+ &pcur, uint32_t(space), IBUF_MAX_N_PAGES_MERGED,
&pages[0], &spaces[0], &n_pages,
&mtr);
ib::info() << "Size of pages merged " << sum_sizes;
@@ -2790,9 +2786,7 @@ ibuf_get_volume_buffered(
ulint volume;
const rec_t* rec;
const page_t* page;
- ulint prev_page_no;
const page_t* prev_page;
- ulint next_page_no;
const page_t* next_page;
/* bitmap of buffered recs */
ulint hash_bitmap[128 / sizeof(ulint)];
@@ -2817,6 +2811,8 @@ ibuf_get_volume_buffered(
rec = page_rec_get_prev_const(rec);
}
+ uint32_t prev_page_no;
+
for (; !page_rec_is_infimum(rec);
rec = page_rec_get_prev_const(rec)) {
ut_ad(page_align(rec) == page);
@@ -2909,7 +2905,7 @@ count_later:
/* Look at the next page */
- next_page_no = btr_page_get_next(page);
+ uint32_t next_page_no = btr_page_get_next(page);
if (next_page_no == FIL_NULL) {
@@ -3197,8 +3193,8 @@ ibuf_insert_low(
page_t* root;
dberr_t err;
ibool do_merge;
- ulint space_ids[IBUF_MAX_N_PAGES_MERGED];
- ulint page_nos[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t space_ids[IBUF_MAX_N_PAGES_MERGED];
+ uint32_t page_nos[IBUF_MAX_N_PAGES_MERGED];
ulint n_stored;
mtr_t mtr;
mtr_t bitmap_mtr;
@@ -4012,14 +4008,12 @@ ibuf_delete(
/*********************************************************************//**
Restores insert buffer tree cursor position
-@return TRUE if the position was restored; FALSE if not */
+@return whether the position was restored */
static MY_ATTRIBUTE((nonnull))
-ibool
+bool
ibuf_restore_pos(
/*=============*/
- ulint space, /*!< in: space id */
- ulint page_no,/*!< in: index page number where the record
- should belong */
+ const page_id_t page_id,/*!< in: page identifier */
const dtuple_t* search_tuple,
/*!< in: search tuple for entries of page_no */
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
@@ -4030,15 +4024,14 @@ ibuf_restore_pos(
ut_ad(mode == BTR_MODIFY_LEAF
|| BTR_LATCH_MODE_WITHOUT_INTENTION(mode) == BTR_MODIFY_TREE);
- if (btr_pcur_restore_position(mode, pcur, mtr)) {
-
- return(TRUE);
+ if (UNIV_LIKELY(btr_pcur_restore_position(mode, pcur, mtr))) {
+ return true;
}
- if (fil_space_t* s = fil_space_acquire_silent(space)) {
+ if (fil_space_t* s = fil_space_t::get(page_id.space())) {
ib::error() << "ibuf cursor restoration fails!"
" ibuf record inserted to page "
- << space << ":" << page_no
+ << page_id
<< " in file " << s->chain.start->name;
s->release();
@@ -4053,19 +4046,18 @@ ibuf_restore_pos(
}
ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
- return(FALSE);
+ return false;
}
/**
Delete a change buffer record.
-@param[in] space tablespace identifier
-@param[in] page_no page number
+@param[in] page_id page identifier
@param[in,out] pcur persistent cursor positioned on the record
@param[in] search_tuple search key for (space,page_no)
@param[in,out] mtr mini-transaction
@return whether mtr was committed (due to pessimistic operation) */
static MY_ATTRIBUTE((warn_unused_result, nonnull))
-bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
+bool ibuf_delete_rec(const page_id_t page_id, btr_pcur_t* pcur,
const dtuple_t* search_tuple, mtr_t* mtr)
{
ibool success;
@@ -4074,14 +4066,14 @@ bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
ut_ad(ibuf_inside(mtr));
ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
- ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
- ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
+ ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur))
+ == page_id.page_no());
+ ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur))
+ == page_id.space());
success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur),
0, mtr);
- const page_id_t page_id(space, page_no);
-
if (success) {
if (page_is_empty(btr_pcur_get_page(pcur))) {
/* If a B-tree page is empty, it must be the root page
@@ -4102,10 +4094,6 @@ bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
return(FALSE);
}
- ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
- ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
- ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
-
/* We have to resort to a pessimistic delete from ibuf.
Delete-mark the record so that it will not be applied again,
in case the server crashes before the pessimistic delete is
@@ -4119,7 +4107,7 @@ bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
ibuf_mtr_start(mtr);
mutex_enter(&ibuf_mutex);
- if (!ibuf_restore_pos(space, page_no, search_tuple,
+ if (!ibuf_restore_pos(page_id, search_tuple,
BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
pcur, mtr)) {
@@ -4226,7 +4214,7 @@ ibuf_merge_or_delete_for_page(
fil_space_t* space;
if (update_ibuf_bitmap) {
- space = fil_space_acquire_silent(page_id.space());
+ space = fil_space_t::get(page_id.space());
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from the
@@ -4441,9 +4429,7 @@ loop:
buf_block_dbg_add_level(
block, SYNC_IBUF_TREE_NODE);
- if (!ibuf_restore_pos(page_id.space(),
- page_id.page_no(),
- search_tuple,
+ if (!ibuf_restore_pos(page_id, search_tuple,
BTR_MODIFY_LEAF,
&pcur, &mtr)) {
@@ -4466,8 +4452,7 @@ loop:
}
/* Delete the record from ibuf */
- if (ibuf_delete_rec(page_id.space(), page_id.page_no(),
- &pcur, search_tuple, &mtr)) {
+ if (ibuf_delete_rec(page_id, &pcur, search_tuple, &mtr)) {
/* Deletion was pessimistic and mtr was committed:
we start from the beginning again */
@@ -4519,7 +4504,6 @@ void ibuf_delete_for_discarded_space(ulint space)
btr_pcur_t pcur;
dtuple_t* search_tuple;
const rec_t* ibuf_rec;
- ulint page_no;
mtr_t mtr;
/* Counts for discarded operations. */
@@ -4558,13 +4542,13 @@ loop:
goto leave_loop;
}
- page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
+ uint32_t page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
/* Delete the record from ibuf */
- if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
- &mtr)) {
+ if (ibuf_delete_rec(page_id_t(space, page_no),
+ &pcur, search_tuple, &mtr)) {
/* Deletion was pessimistic and mtr was committed:
we start from the beginning again */
@@ -4642,37 +4626,20 @@ ibuf_print(
@return DB_SUCCESS or error code */
dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
{
- ulint page_no;
ut_ad(trx->mysql_thd);
ut_ad(space->purpose == FIL_TYPE_IMPORT);
- const ulint zip_size = space->zip_size();
- const ulint physical_size = space->physical_size();
- /* fil_space_t::size and fil_space_t::free_limit would still be 0
- at this point. So, we will have to read page 0. */
- ut_ad(!space->free_limit);
- ut_ad(!space->size);
+ const unsigned zip_size = space->zip_size();
+ const unsigned physical_size = space->physical_size();
- mtr_t mtr;
- ulint size;
- mtr.start();
- if (buf_block_t* sp = buf_page_get(page_id_t(space->id, 0),
- zip_size,
- RW_S_LATCH, &mtr)) {
- size = std::min(
- mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
- + sp->frame),
- mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
- + sp->frame));
- } else {
- size = 0;
- }
- mtr.commit();
+ uint32_t size= std::min(space->free_limit, space->size);
if (size == 0) {
return(DB_TABLE_NOT_FOUND);
}
+ mtr_t mtr;
+
mutex_enter(&ibuf_mutex);
/* The two bitmap pages (allocation bitmap and ibuf bitmap) repeat
@@ -4681,7 +4648,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
below page_no is measured in number of pages since the beginning of
the space, as usual. */
- for (page_no = 0; page_no < size; page_no += physical_size) {
+ for (uint32_t page_no = 0; page_no < size; page_no += physical_size) {
if (trx_is_interrupted(trx)) {
mutex_exit(&ibuf_mutex);
return(DB_INTERRUPTED);
@@ -4707,7 +4674,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
ibuf bitmap page. The subsequent page should be
all-zero pages. */
#ifdef UNIV_DEBUG
- for (ulint curr_page = page_no + 1;
+ for (uint32_t curr_page = page_no + 1;
curr_page < physical_size; curr_page++) {
buf_block_t* block = buf_page_get(
@@ -4724,9 +4691,9 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
continue;
}
- for (ulint i = FSP_IBUF_BITMAP_OFFSET + 1; i < physical_size;
+ for (uint32_t i = FSP_IBUF_BITMAP_OFFSET + 1; i < physical_size;
i++) {
- const ulint offset = page_no + i;
+ const uint32_t offset = page_no + i;
const page_id_t cur_page_id(space->id, offset);
if (ibuf_bitmap_page_get_bits(
@@ -4740,7 +4707,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
ib_errf(trx->mysql_thd,
IB_LOG_LEVEL_ERROR,
ER_INNODB_INDEX_CORRUPT,
- "File %s page " ULINTPF
+ "File %s page %u"
" is wrongly flagged to belong to the"
" insert buffer",
space->chain.start->name, offset);
@@ -4755,8 +4722,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
IB_LOG_LEVEL_WARN,
ER_INNODB_INDEX_CORRUPT,
"Buffered changes"
- " for file %s page " ULINTPF
- " are lost",
+ " for file %s page %u are lost",
space->chain.start->name, offset);
/* Tolerate this error, so that
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index b02c65f3a31..7fae1ad163b 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -214,7 +214,7 @@ the index.
ulint
btr_height_get(
/*===========*/
- dict_index_t* index, /*!< in: index tree */
+ const dict_index_t* index, /*!< in: index tree */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((warn_unused_result));
@@ -227,8 +227,8 @@ btr_height_get(
@param[in] line line where called
@param[in,out] mtr mini-transaction
@return block */
-inline buf_block_t* btr_block_get_func(const dict_index_t& index, ulint page,
- ulint mode, bool merge,
+inline buf_block_t* btr_block_get_func(const dict_index_t& index,
+ uint32_t page, ulint mode, bool merge,
const char* file, unsigned line,
mtr_t* mtr)
{
@@ -323,7 +323,7 @@ the child page number. In other words offsets must have been retrieved
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
@return child node address */
UNIV_INLINE
-ulint
+uint32_t
btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
@@ -579,7 +579,7 @@ Gets the number of pages in a B-tree.
ulint
btr_get_size(
/*=========*/
- dict_index_t* index, /*!< in: index */
+ const dict_index_t* index, /*!< in: index */
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
@@ -607,7 +607,7 @@ buf_block_t*
btr_page_alloc(
/*===========*/
dict_index_t* index, /*!< in: index tree */
- ulint hint_page_no, /*!< in: hint of a good page */
+ uint32_t hint_page_no, /*!< in: hint of a good page */
byte file_direction, /*!< in: direction where a possible
page split is made */
ulint level, /*!< in: level where the page is placed
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index 5d2faa1e298..89826e8f214 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -90,7 +90,7 @@ the child page number. In other words offsets must have been retrieved
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
@return child node address */
UNIV_INLINE
-ulint
+uint32_t
btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
@@ -98,7 +98,6 @@ btr_node_ptr_get_child_page_no(
{
const byte* field;
ulint len;
- ulint page_no;
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
@@ -108,7 +107,7 @@ btr_node_ptr_get_child_page_no(
ut_ad(len == 4);
- page_no = mach_read_from_4(field);
+ uint32_t page_no = mach_read_from_4(field);
ut_ad(page_no > 1);
return(page_no);
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index dc28d15b391..375b7b34fe4 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -57,7 +57,7 @@ public:
PageBulk(
dict_index_t* index,
trx_id_t trx_id,
- ulint page_no,
+ uint32_t page_no,
ulint level)
:
m_heap(NULL),
@@ -179,10 +179,7 @@ public:
inline bool isSpaceAvailable(ulint rec_size);
/** Get page no */
- ulint getPageNo()
- {
- return(m_page_no);
- }
+ uint32_t getPageNo() const { return m_page_no; }
/** Get page level */
ulint getLevel()
@@ -241,7 +238,7 @@ private:
rec_t* m_cur_rec;
/** The page no */
- ulint m_page_no;
+ uint32_t m_page_no;
/** The page level in B-tree */
ulint m_level;
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 03ebf6f448f..7136d726db0 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -590,8 +590,24 @@ btr_estimate_n_rows_in_range(
btr_pos_t* range_start,
btr_pos_t* range_end);
-/*******************************************************************//**
-Estimates the number of different key values in a given index, for
+
+/** Statistics for one field of an index. */
+struct index_field_stats_t
+{
+ ib_uint64_t n_diff_key_vals;
+ ib_uint64_t n_sample_sizes;
+ ib_uint64_t n_non_null_key_vals;
+
+ index_field_stats_t(ib_uint64_t n_diff_key_vals= 0,
+ ib_uint64_t n_sample_sizes= 0,
+ ib_uint64_t n_non_null_key_vals= 0)
+ : n_diff_key_vals(n_diff_key_vals), n_sample_sizes(n_sample_sizes),
+ n_non_null_key_vals(n_non_null_key_vals)
+ {
+ }
+};
+
+/** Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals[] (indexed
0..n_uniq-1) and the number of pages that were sampled is saved in
@@ -599,12 +615,11 @@ index->stat_n_sample_sizes[].
If innodb_stats_method is nulls_ignored, we also record the number of
non-null values for each prefix and stored the estimates in
array index->stat_n_non_null_key_vals.
-@return true if the index is available and we get the estimated numbers,
-false if the index is unavailable. */
-bool
-btr_estimate_number_of_different_key_vals(
-/*======================================*/
- dict_index_t* index); /*!< in: index */
+@param[in] index index
+@return stat vector if the index is available and we get the estimated numbers,
+empty vector if the index is unavailable. */
+std::vector<index_field_stats_t>
+btr_estimate_number_of_different_key_vals(dict_index_t* index);
/** Gets the externally stored size of a record, in units of a database page.
@param[in] rec record
@@ -799,7 +814,7 @@ struct btr_path_t {
ulint n_recs;
/** Number of the page containing the record. */
- ulint page_no;
+ uint32_t page_no;
/** Level of the page. If later we fetch the page under page_no
and it is no different level then we know that the tree has been
diff --git a/storage/innobase/include/btr0defragment.h b/storage/innobase/include/btr0defragment.h
index ed543477bcc..a9212db0e04 100644
--- a/storage/innobase/include/btr0defragment.h
+++ b/storage/innobase/include/btr0defragment.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, 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
@@ -30,21 +30,6 @@ extern Atomic_counter<ulint> btr_defragment_compression_failures;
extern Atomic_counter<ulint> btr_defragment_failures;
extern Atomic_counter<ulint> btr_defragment_count;
-/** Item in the work queue for btr_degrament_thread. */
-struct btr_defragment_item_t
-{
- btr_pcur_t* pcur; /* persistent cursor where
- btr_defragment_n_pages should start */
- os_event_t event; /* if not null, signal after work
- is done */
- bool removed; /* Mark an item as removed */
- ulonglong last_processed; /* timestamp of last time this index
- is processed by defragment thread */
-
- btr_defragment_item_t(btr_pcur_t* pcur, os_event_t event);
- ~btr_defragment_item_t();
-};
-
/******************************************************************//**
Initialize defragmentation. */
void
@@ -64,8 +49,6 @@ is a synchronized defragmentation. */
os_event_t
btr_defragment_add_index(
dict_index_t* index, /*!< index to be added */
- bool async, /*!< whether this is an async
- defragmentation */
dberr_t* err); /*!< out: error code */
/******************************************************************//**
When table is dropped, this function is called to mark a table as removed in
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index bceb35a6969..bc7afbf3b67 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -29,6 +29,7 @@ Created 2/23/1996 Heikki Tuuri
#include "dict0dict.h"
#include "btr0cur.h"
+#include "buf0block_hint.h"
#include "btr0btr.h"
#include "gis0rtree.h"
@@ -502,13 +503,10 @@ struct btr_pcur_t{
whether cursor was on, before, or after the old_rec record */
enum btr_pcur_pos_t rel_pos;
/** buffer block when the position was stored */
- buf_block_t* block_when_stored;
+ buf::Block_hint block_when_stored;
/** the modify clock value of the buffer block when the cursor position
was stored */
ib_uint64_t modify_clock;
- /** the withdraw clock value of the buffer pool when the cursor
- position was stored */
- ulint withdraw_clock;
/** btr_pcur_store_position() and btr_pcur_restore_position() state. */
enum pcur_pos_t pos_state;
/** PAGE_CUR_G, ... */
@@ -529,9 +527,8 @@ struct btr_pcur_t{
btr_cur(), latch_mode(RW_NO_LATCH),
old_stored(false), old_rec(NULL),
old_n_fields(0), rel_pos(btr_pcur_pos_t(0)),
- block_when_stored(NULL),
- modify_clock(0), withdraw_clock(0),
- pos_state(BTR_PCUR_NOT_POSITIONED),
+ block_when_stored(),
+ modify_clock(0), pos_state(BTR_PCUR_NOT_POSITIONED),
search_mode(PAGE_CUR_UNSUPP), trx_if_known(NULL),
old_rec_buf(NULL), buf_size(0)
{
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index f09920b1816..f8f2050d3d3 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -192,8 +192,6 @@ struct btr_search_t{
the machine word, i.e., they cannot be turned into bit-fields. */
buf_block_t* root_guess;/*!< the root page frame when it was last time
fetched, or NULL */
- ulint withdraw_clock; /*!< the withdraw clock value of the buffer
- pool when root_guess was stored */
#ifdef BTR_CUR_HASH_ADAPT
ulint hash_analysis; /*!< when this exceeds
BTR_SEARCH_HASH_ANALYSIS, the hash
diff --git a/storage/innobase/include/buf0block_hint.h b/storage/innobase/include/buf0block_hint.h
new file mode 100644
index 00000000000..ee48e7ce6d2
--- /dev/null
+++ b/storage/innobase/include/buf0block_hint.h
@@ -0,0 +1,76 @@
+/*****************************************************************************
+
+Copyright (c) 2020, 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, 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, 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, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+*****************************************************************************/
+#pragma once
+#include "buf0buf.h"
+
+namespace buf {
+class Block_hint {
+public:
+ /** Stores the pointer to the block, which is currently buffer-fixed.
+ @param block a pointer to a buffer-fixed block to be stored */
+ inline void store(buf_block_t *block)
+ {
+ ut_ad(block->page.buf_fix_count());
+ m_block= block;
+ m_page_id= block->page.id();
+ }
+
+ /** Clears currently stored pointer. */
+ inline void clear() { m_block= nullptr; }
+
+ /** Invoke f on m_block(which may be null)
+ @param f The function to be executed. It will be passed the pointer.
+ If you wish to use the block pointer subsequently,
+ you need to ensure you buffer-fix it before returning from f.
+ @return the return value of f
+ */
+ template <typename F>
+ bool run_with_hint(const F &f)
+ {
+ buffer_fix_block_if_still_valid();
+ /* m_block could be changed during f() call, so we use local
+ variable to remember which block we need to unfix */
+ buf_block_t *block= m_block;
+ bool res= f(block);
+ if (block)
+ buf_block_buf_fix_dec(block);
+ return res;
+ }
+
+ buf_block_t *block() const { return m_block; }
+
+ private:
+ /** The block pointer stored by store(). */
+ buf_block_t *m_block= nullptr;
+ /** If m_block is non-null, the m_block->page.id at time it was stored. */
+ page_id_t m_page_id{0, 0};
+
+ /** A helper function which checks if m_block is not a dangling pointer and
+ still points to block with page with m_page_id and if so, buffer-fixes it,
+ otherwise clear()s it */
+ void buffer_fix_block_if_still_valid();
+};
+} // namespace buf
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 04d74b6e36f..df52d6b572c 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -39,7 +39,6 @@ Created 11/5/1995 Heikki Tuuri
#include "hash0hash.h"
#include "ut0byte.h"
#include "page0types.h"
-#include "ut0rbt.h"
#include "log0log.h"
#include "srv0srv.h"
#include <ostream>
@@ -105,10 +104,6 @@ struct buf_pool_info_t
ulint n_pend_reads; /*!< buf_pool.n_pend_reads, pages
pending read */
ulint n_pending_flush_lru; /*!< Pages pending flush in LRU */
- ulint n_pending_flush_single_page;/*!< Pages pending to be
- flushed as part of single page
- flushes issued by various user
- threads */
ulint n_pending_flush_list; /*!< Pages pending flush in FLUSH
LIST */
ulint n_pages_made_young; /*!< number of pages made young */
@@ -340,10 +335,11 @@ FILE_PAGE (the other is buf_page_get_gen).
@param[in] offset offset of the tablespace
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in,out] mtr mini-transaction
+@param[in,out] free_block pre-allocated buffer block
@return pointer to the block, page bufferfixed */
buf_block_t*
buf_page_create(fil_space_t *space, uint32_t offset,
- ulint zip_size, mtr_t *mtr);
+ ulint zip_size, mtr_t *mtr, buf_block_t *free_block);
/********************************************************************//**
Releases a compressed-only page acquired with buf_page_get_zip(). */
@@ -818,15 +814,11 @@ public:
state() == BUF_BLOCK_NOT_USED: buf_pool.free or buf_pool.withdraw
- state() == BUF_BLOCK_FILE_PAGE ||
- (state() == BUF_BLOCK_ZIP_PAGE && !oldest_modification()):
+ in_file() && oldest_modification():
buf_pool.flush_list (protected by buf_pool.flush_list_mutex)
- state() == BUF_BLOCK_ZIP_PAGE && !oldest_modification(): buf_pool.zip_clean
-
- The contents is undefined if
- !oldest_modification() && state() == BUF_BLOCK_FILE_PAGE,
- or if state() is not any of the above. */
+ The contents is undefined if in_file() && !oldest_modification(),
+ or if state() is BUF_BLOCK_MEMORY or BUF_BLOCK_REMOVE_HASH. */
UT_LIST_NODE_T(buf_page_t) list;
private:
@@ -986,6 +978,15 @@ public:
return zip.ssize ? (UNIV_ZIP_SIZE_MIN >> 1) << zip.ssize : 0;
}
+ /** @return the byte offset of the page within a file */
+ os_offset_t physical_offset() const
+ {
+ os_offset_t o= id().page_no();
+ return zip.ssize
+ ? o << (zip.ssize + (UNIV_ZIP_SIZE_SHIFT_MIN - 1))
+ : o << srv_page_size_shift;
+ }
+
/** @return whether the block is mapped to a data file */
bool in_file() const
{
@@ -1043,7 +1044,7 @@ struct buf_block_t{
is of size srv_page_size, and
aligned to an address divisible by
srv_page_size */
- BPageLock lock; /*!< read-write lock of the buffer
+ rw_lock_t lock; /*!< read-write lock of the buffer
frame */
#ifdef UNIV_DEBUG
/** whether page.list is in buf_pool.withdraw
@@ -1219,13 +1220,13 @@ public:
virtual ~HazardPointer() {}
/** @return current value */
- buf_page_t *get() const { ut_ad(mutex_own(m_mutex)); return m_hp; }
+ buf_page_t *get() const { mysql_mutex_assert_owner(m_mutex); return m_hp; }
/** Set current value
@param bpage buffer block to be set as hp */
void set(buf_page_t *bpage)
{
- ut_ad(mutex_own(m_mutex));
+ mysql_mutex_assert_owner(m_mutex);
ut_ad(!bpage || bpage->in_file());
m_hp= bpage;
}
@@ -1234,7 +1235,7 @@ public:
@param bpage buffer block to be compared
@return true if it is hp */
bool is_hp(const buf_page_t *bpage) const
- { ut_ad(mutex_own(m_mutex)); return bpage == m_hp; }
+ { mysql_mutex_assert_owner(m_mutex); return bpage == m_hp; }
/** Adjust the value of hp. This happens when some
other thread working on the same list attempts to
@@ -1243,7 +1244,7 @@ public:
#ifdef UNIV_DEBUG
/** mutex that protects access to the m_hp. */
- const ib_mutex_t *m_mutex= nullptr;
+ const mysql_mutex_t *m_mutex= nullptr;
#endif /* UNIV_DEBUG */
protected:
@@ -1466,21 +1467,7 @@ public:
/** @return whether resize() is in progress */
bool resize_in_progress() const
{
- return UNIV_UNLIKELY(resizing.load(std::memory_order_relaxed) ||
- withdrawing.load(std::memory_order_relaxed));
- }
-
- /** @return the withdraw_clock */
- ulint withdraw_clock() const
- { return withdraw_clock_.load(std::memory_order_relaxed); }
-
- /** Verify the possibility that a stored page is not in buffer pool.
- @param withdraw_clock the withdraw clock of the page
- @return whether the page might be relocated */
- bool is_obsolete(ulint withdraw_clock) const
- {
- return UNIV_UNLIKELY(withdrawing.load(std::memory_order_relaxed) ||
- this->withdraw_clock() != withdraw_clock);
+ return UNIV_UNLIKELY(resizing.load(std::memory_order_relaxed));
}
/** @return the current size in blocks */
@@ -1499,7 +1486,10 @@ public:
bool will_be_withdrawn(const byte *ptr) const
{
ut_ad(curr_size < old_size);
- ut_ad(!resizing.load(std::memory_order_relaxed) || mutex_own(&mutex));
+#ifdef SAFE_MUTEX
+ if (resizing.load(std::memory_order_relaxed))
+ mysql_mutex_assert_owner(&mutex);
+#endif /* SAFE_MUTEX */
for (const chunk_t *chunk= chunks + n_chunks_new,
* const echunk= chunks + n_chunks;
@@ -1516,7 +1506,10 @@ public:
bool will_be_withdrawn(const buf_page_t &bpage) const
{
ut_ad(curr_size < old_size);
- ut_ad(!resizing.load(std::memory_order_relaxed) || mutex_own(&mutex));
+#ifdef SAFE_MUTEX
+ if (resizing.load(std::memory_order_relaxed))
+ mysql_mutex_assert_owner(&mutex);
+#endif /* SAFE_MUTEX */
for (const chunk_t *chunk= chunks + n_chunks_new,
* const echunk= chunks + n_chunks;
@@ -1529,7 +1522,10 @@ public:
/** Release and evict a corrupted page.
@param bpage page that was being read */
- void corrupted_evict(buf_page_t *bpage);
+ ATTRIBUTE_COLD void corrupted_evict(buf_page_t *bpage);
+
+ /** Release a memory block to the buffer pool. */
+ ATTRIBUTE_COLD void free_block(buf_block_t *block);
#ifdef UNIV_DEBUG
/** Find a block that points to a ROW_FORMAT=COMPRESSED page
@@ -1538,7 +1534,7 @@ public:
@retval nullptr if not found */
const buf_block_t *contains_zip(const void *data) const
{
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
for (const chunk_t *chunk= chunks, * const end= chunks + n_chunks;
chunk != end; chunk++)
if (const buf_block_t *block= chunk->contains_zip(data))
@@ -1561,22 +1557,30 @@ public:
inline buf_block_t *block_from_ahi(const byte *ptr) const;
#endif /* BTR_CUR_HASH_ADAPT */
- bool is_block_lock(const BPageLock *l) const
- { return is_block_field(reinterpret_cast<const void*>(l)); }
+ bool is_block_lock(const rw_lock_t *l) const
+ { return is_block_field(static_cast<const void*>(l)); }
/**
@return the smallest oldest_modification lsn for any page
- @retval 0 if all modified persistent pages have been flushed */
- lsn_t get_oldest_modification();
+ @retval empty_lsn if all modified persistent pages have been flushed */
+ lsn_t get_oldest_modification(lsn_t empty_lsn)
+ {
+ mysql_mutex_assert_owner(&flush_list_mutex);
+ const buf_page_t *bpage= UT_LIST_GET_LAST(flush_list);
+#if 1 /* MDEV-12227 FIXME: remove this loop */
+ for (; bpage && fsp_is_system_temporary(bpage->id().space());
+ bpage= UT_LIST_GET_PREV(list, bpage))
+ ut_ad(bpage->oldest_modification());
+#endif
+ return bpage ? bpage->oldest_modification() : empty_lsn;
+ }
/** Determine if a buffer block was created by chunk_t::create().
@param block block descriptor (not dereferenced)
@return whether block has been created by chunk_t::create() */
bool is_uncompressed(const buf_block_t *block) const
{
- /* The pointer should be aligned. */
- return !(size_t(block) % sizeof *block) &&
- is_block_field(reinterpret_cast<const void*>(block));
+ return is_block_field(reinterpret_cast<const void*>(block));
}
/** Get the page_hash latch for a page */
@@ -1593,7 +1597,10 @@ public:
buf_page_t *page_hash_get_low(const page_id_t id, const ulint fold)
{
ut_ad(id.fold() == fold);
- ut_ad(mutex_own(&mutex) || page_hash.lock_get(fold)->is_locked());
+#ifdef SAFE_MUTEX
+ DBUG_ASSERT(mysql_mutex_is_owner(&mutex) ||
+ page_hash.lock_get(fold)->is_locked());
+#endif /* SAFE_MUTEX */
buf_page_t *bpage;
/* Look for the page in the hash table */
HASH_SEARCH(hash, &page_hash, fold, buf_page_t*, bpage,
@@ -1660,7 +1667,10 @@ public:
@return whether bpage a sentinel for a buffer pool watch */
bool watch_is_sentinel(const buf_page_t &bpage)
{
- ut_ad(mutex_own(&mutex) || hash_lock_get(bpage.id())->is_locked());
+#ifdef SAFE_MUTEX
+ DBUG_ASSERT(mysql_mutex_is_owner(&mutex) ||
+ hash_lock_get(bpage.id())->is_locked());
+#endif /* SAFE_MUTEX */
ut_ad(bpage.in_file());
if (&bpage < &watch[0] || &bpage >= &watch[UT_ARR_SIZE(watch)])
@@ -1717,7 +1727,7 @@ public:
HASH_DELETE(buf_page_t, hash, &page_hash, fold, watch);
hash_lock->write_unlock();
// Now that the watch is detached from page_hash, release it to watch[].
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
/* It is possible that watch_remove() already removed the watch. */
if (watch->id_ == id)
{
@@ -1725,7 +1735,7 @@ public:
ut_ad(watch->state() == BUF_BLOCK_ZIP_PAGE);
watch->set_state(BUF_BLOCK_NOT_USED);
}
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
}
else
hash_lock->write_unlock();
@@ -1758,14 +1768,13 @@ public:
@return the predecessor in the LRU list */
buf_page_t *LRU_remove(buf_page_t *bpage)
{
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
ut_ad(bpage->in_LRU_list);
ut_ad(bpage->in_page_hash);
ut_ad(!bpage->in_zip_hash);
ut_ad(bpage->in_file());
lru_hp.adjust(bpage);
lru_scan_itr.adjust(bpage);
- single_scan_itr.adjust(bpage);
ut_d(bpage->in_LRU_list= false);
buf_page_t *prev= UT_LIST_GET_PREV(LRU, bpage);
UT_LIST_REMOVE(LRU, bpage);
@@ -1775,9 +1784,19 @@ public:
/** Number of pages to read ahead */
static constexpr uint32_t READ_AHEAD_PAGES= 64;
+ /** Buffer pool mutex */
+ mysql_mutex_t mutex;
+ /** Number of pending LRU flush. */
+ Atomic_counter<ulint> n_flush_LRU;
+ /** broadcast when n_flush_LRU reaches 0; protected by mutex */
+ mysql_cond_t done_flush_LRU;
+ /** Number of pending flush_list flush. */
+ Atomic_counter<ulint> n_flush_list;
+ /** broadcast when n_flush_list reaches 0; protected by mutex */
+ mysql_cond_t done_flush_list;
+
/** @name General fields */
/* @{ */
- BufPoolMutex mutex; /*!< Buffer pool mutex */
ulint curr_pool_size; /*!< Current pool size in bytes */
ulint LRU_old_ratio; /*!< Reserve this much of the buffer
pool for "old" blocks */
@@ -1908,50 +1927,23 @@ public:
/* @} */
- /** @name Page flushing algorithm fields */
+ /** @name Page flushing algorithm fields */
+ /* @{ */
- /* @{ */
+ /** mutex protecting flush_list, buf_page_t::set_oldest_modification()
+ and buf_page_t::list pointers when !oldest_modification() */
+ mysql_mutex_t flush_list_mutex;
+ /** "hazard pointer" for flush_list scans; protected by flush_list_mutex */
+ FlushHp flush_hp;
+ /** modified blocks (a subset of LRU) */
+ UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
+
+ /** signalled to wake up the page_cleaner; protected by flush_list_mutex */
+ mysql_cond_t do_flush_list;
+
+ // n_flush_LRU + n_flush_list is approximately COUNT(io_fix()==BUF_IO_WRITE)
+ // in flush_list
- FlushListMutex flush_list_mutex;/*!< mutex protecting the
- flush list access. This mutex
- protects flush_list, flush_rbt
- and bpage::list pointers when
- the bpage is on flush_list. It
- also protects writes to
- bpage::oldest_modification and
- flush_list_hp */
- FlushHp flush_hp;/*!< "hazard pointer"
- used during scan of flush_list
- while doing flush list batch.
- Protected by flush_list_mutex */
- UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
- /*!< base node of the modified block
- list */
- /** set if a flush of the type is being initialized */
- Atomic_relaxed<bool> init_flush[3];
- /** Number of pending writes of a flush type.
- The sum of these is approximately the sum of BUF_IO_WRITE blocks. */
- Atomic_counter<ulint> n_flush[3];
- os_event_t no_flush[3];
- /*!< this is in the set state
- when there is no flush batch
- of the given type running;
- os_event_set() and os_event_reset()
- are protected by buf_pool_t::mutex */
- ib_rbt_t* flush_rbt; /*!< a red-black tree is used
- exclusively during recovery to
- speed up insertions in the
- flush_list. This tree contains
- blocks in order of
- oldest_modification LSN and is
- kept in sync with the
- flush_list.
- Each member of the tree MUST
- also be on the flush_list.
- This tree is relevant only in
- recovery and is set to NULL
- once the recovery is over.
- Protected by flush_list_mutex */
unsigned freed_page_clock;/*!< a sequence number used
to count the number of buffer
blocks removed from the end of
@@ -1997,10 +1989,6 @@ public:
replacable victim. Protected by buf_pool_t::mutex. */
LRUItr lru_scan_itr;
- /** Iterator used to scan the LRU list when searching for
- single page flushing victim. Protected by buf_pool_t::mutex. */
- LRUItr single_scan_itr;
-
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
/*!< base node of the LRU list */
@@ -2024,22 +2012,11 @@ public:
unzip_LRU list */
/* @} */
- /** @name Buddy allocator fields
- The buddy allocator is used for allocating compressed page
- frames and buf_page_t descriptors of blocks that exist
- in the buffer pool only in compressed form. */
- /* @{ */
-#ifdef UNIV_DEBUG
- /** unmodified ROW_FORMAT=COMPRESSED pages;
- protected by buf_pool.mutex */
- UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
-#endif /* UNIV_DEBUG */
- UT_LIST_BASE_NODE_T(buf_buddy_free_t) zip_free[BUF_BUDDY_SIZES_MAX];
- /*!< buddy free lists */
+ /** free ROW_FORMAT=COMPRESSED page frames */
+ UT_LIST_BASE_NODE_T(buf_buddy_free_t) zip_free[BUF_BUDDY_SIZES_MAX];
#if BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN
# error "BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN"
#endif
- /* @} */
/** Sentinels to detect if pages are read into the buffer pool while
a delete-buffering operation is pending. Protected by mutex. */
@@ -2050,16 +2027,12 @@ public:
/** @return whether any I/O is pending */
bool any_io_pending() const
{
- return n_pend_reads ||
- n_flush[IORequest::LRU] || n_flush[IORequest::FLUSH_LIST] ||
- n_flush[IORequest::SINGLE_PAGE];
+ return n_pend_reads || n_flush_LRU || n_flush_list;
}
/** @return total amount of pending I/O */
ulint io_pending() const
{
- return n_pend_reads +
- n_flush[IORequest::LRU] + n_flush[IORequest::FLUSH_LIST] +
- n_flush[IORequest::SINGLE_PAGE];
+ return n_pend_reads + n_flush_LRU + n_flush_list;
}
private:
/** Temporary memory for page_compressed and encrypted I/O */
@@ -2102,13 +2075,6 @@ private:
/** whether resize() is in the critical path */
std::atomic<bool> resizing;
-
- /** whether withdrawing buffer pool pages might cause page relocation */
- std::atomic<bool> withdrawing;
-
- /** a counter that is incremented every time a pointer to a page may
- become obsolete */
- std::atomic<ulint> withdraw_clock_;
};
/** The InnoDB buffer pool */
@@ -2116,7 +2082,7 @@ extern buf_pool_t buf_pool;
inline void page_hash_latch::read_lock()
{
- ut_ad(!mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_not_owner(&buf_pool.mutex);
if (!read_trylock())
read_lock_wait();
}
@@ -2129,19 +2095,19 @@ inline void page_hash_latch::write_lock()
inline void buf_page_t::add_buf_fix_count(uint32_t count)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
buf_fix_count_+= count;
}
inline void buf_page_t::set_buf_fix_count(uint32_t count)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
buf_fix_count_= count;
}
inline void buf_page_t::set_state(buf_page_state state)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
#ifdef UNIV_DEBUG
switch (state) {
case BUF_BLOCK_REMOVE_HASH:
@@ -2170,7 +2136,7 @@ inline void buf_page_t::set_state(buf_page_state state)
inline void buf_page_t::set_io_fix(buf_io_fix io_fix)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
io_fix_= io_fix;
}
@@ -2196,7 +2162,7 @@ inline void buf_page_t::set_corrupt_id()
/** Set oldest_modification when adding to buf_pool.flush_list */
inline void buf_page_t::set_oldest_modification(lsn_t lsn)
{
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
+ mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
ut_ad(!oldest_modification());
oldest_modification_= lsn;
}
@@ -2204,7 +2170,7 @@ inline void buf_page_t::set_oldest_modification(lsn_t lsn)
/** Clear oldest_modification when removing from buf_pool.flush_list */
inline void buf_page_t::clear_oldest_modification()
{
- ut_ad(mutex_own(&buf_pool.flush_list_mutex));
+ mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
ut_d(const auto state= state_);
ut_ad(state == BUF_BLOCK_FILE_PAGE || state == BUF_BLOCK_ZIP_PAGE ||
state == BUF_BLOCK_REMOVE_HASH);
@@ -2215,7 +2181,7 @@ inline void buf_page_t::clear_oldest_modification()
/** @return whether the block is modified and ready for flushing */
inline bool buf_page_t::ready_for_flush() const
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(in_LRU_list);
ut_a(in_file());
return oldest_modification() && io_fix_ == BUF_IO_NONE;
@@ -2225,7 +2191,7 @@ inline bool buf_page_t::ready_for_flush() const
The block can be dirty, but it must not be I/O-fixed or bufferfixed. */
inline bool buf_page_t::can_relocate() const
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(in_file());
ut_ad(in_LRU_list);
return io_fix_ == BUF_IO_NONE && !buf_fix_count_;
@@ -2234,7 +2200,7 @@ inline bool buf_page_t::can_relocate() const
/** @return whether the block has been flagged old in buf_pool.LRU */
inline bool buf_page_t::is_old() const
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(in_file());
ut_ad(in_LRU_list);
return old;
@@ -2243,7 +2209,7 @@ inline bool buf_page_t::is_old() const
/** Set whether a block is old in buf_pool.LRU */
inline void buf_page_t::set_old(bool old)
{
- ut_ad(mutex_own(&buf_pool.mutex));
+ mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(in_LRU_list);
#ifdef UNIV_LRU_DEBUG
@@ -2270,14 +2236,14 @@ inline void buf_page_t::set_old(bool old)
#ifdef UNIV_DEBUG
/** Forbid the release of the buffer pool mutex. */
-# define buf_pool_mutex_exit_forbid() do { \
- ut_ad(mutex_own(&buf_pool.mutex)); \
- buf_pool.mutex_exit_forbidden++; \
+# define buf_pool_mutex_exit_forbid() do { \
+ mysql_mutex_assert_owner(&buf_pool.mutex); \
+ buf_pool.mutex_exit_forbidden++; \
} while (0)
/** Allow the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_allow() do { \
- ut_ad(mutex_own(&buf_pool.mutex)); \
- ut_ad(buf_pool.mutex_exit_forbidden--); \
+ mysql_mutex_assert_owner(&buf_pool.mutex); \
+ ut_ad(buf_pool.mutex_exit_forbidden--); \
} while (0)
#else
/** Forbid the release of the buffer pool mutex. */
@@ -2295,8 +2261,7 @@ MEMORY: is not in free list, LRU list, or flush list, nor page
hash table
FILE_PAGE: space and offset are defined, is in page hash table
if io_fix == BUF_IO_WRITE,
- pool: no_flush[flush_type] is in reset state,
- pool: n_flush[flush_type] > 0
+ buf_pool.n_flush_LRU > 0 || buf_pool.n_flush_list > 0
(1) if buf_fix_count == 0, then
is in LRU list, not in free list
@@ -2333,7 +2298,7 @@ of the LRU list.
@return buf_page_t from where to start scan. */
inline buf_page_t *LRUItr::start()
{
- ut_ad(mutex_own(m_mutex));
+ mysql_mutex_assert_owner(m_mutex);
if (!m_hp || m_hp->old)
m_hp= UT_LIST_GET_LAST(buf_pool.LRU);
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index 2384c46af02..4d8cef4c4b2 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -198,9 +198,9 @@ buf_block_free(
/*===========*/
buf_block_t* block) /*!< in, own: block to be freed */
{
- mutex_enter(&buf_pool.mutex);
+ mysql_mutex_lock(&buf_pool.mutex);
buf_LRU_block_free_non_file_page(block);
- mutex_exit(&buf_pool.mutex);
+ mysql_mutex_unlock(&buf_pool.mutex);
}
/********************************************************************//**
@@ -213,12 +213,20 @@ buf_block_modify_clock_inc(
/*=======================*/
buf_block_t* block) /*!< in: block */
{
+#ifdef SAFE_MUTEX
/* No latch is acquired for the shared temporary tablespace. */
ut_ad(fsp_is_system_temporary(block->page.id().space())
- || (mutex_own(&buf_pool.mutex)
+ || (mysql_mutex_is_owner(&buf_pool.mutex)
&& !block->page.buf_fix_count())
|| rw_lock_own_flagged(&block->lock,
RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX));
+#else /* SAFE_MUTEX */
+ /* No latch is acquired for the shared temporary tablespace. */
+ ut_ad(fsp_is_system_temporary(block->page.id().space())
+ || !block->page.buf_fix_count()
+ || rw_lock_own_flagged(&block->lock,
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX));
+#endif /* SAFE_MUTEX */
assert_block_ahi_valid(block);
block->modify_clock++;
@@ -280,8 +288,6 @@ buf_block_buf_fix_dec(
/*==================*/
buf_block_t* block) /*!< in/out: block to bufferunfix */
{
- block->unfix();
-
#ifdef UNIV_DEBUG
/* No debug latch is acquired if block belongs to system temporary.
Debug latch is not of much help if access to block is single
@@ -290,6 +296,8 @@ buf_block_buf_fix_dec(
rw_lock_s_unlock(block->debug_latch);
}
#endif /* UNIV_DEBUG */
+
+ block->unfix();
}
/********************************************************************//**
diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h
index fca2c61124e..47517adc40b 100644
--- a/storage/innobase/include/buf0dblwr.h
+++ b/storage/innobase/include/buf0dblwr.h
@@ -24,127 +24,127 @@ Doublewrite buffer module
Created 2011/12/19 Inaam Rana
*******************************************************/
-#ifndef buf0dblwr_h
-#define buf0dblwr_h
+#pragma once
-#include "ut0byte.h"
-#include "log0log.h"
+#include "os0file.h"
#include "buf0types.h"
-#include "log0recv.h"
-
-/** Doublewrite system */
-extern buf_dblwr_t* buf_dblwr;
-/** Set to TRUE when the doublewrite buffer is being created */
-extern ibool buf_dblwr_being_created;
-
-/** Create the doublewrite buffer if the doublewrite buffer header
-is not present in the TRX_SYS page.
-@return whether the operation succeeded
-@retval true if the doublewrite buffer exists or was created
-@retval false if the creation failed (too small first data file) */
-MY_ATTRIBUTE((warn_unused_result))
-bool
-buf_dblwr_create();
-
-/**
-At database startup initializes the doublewrite buffer memory structure if
-we already have a doublewrite buffer created in the data files. If we are
-upgrading to an InnoDB version which supports multiple tablespaces, then this
-function performs the necessary update operations. If we are in a crash
-recovery, this function loads the pages from double write buffer into memory.
-@param[in] file File handle
-@param[in] path Path name of file
-@return DB_SUCCESS or error code */
-dberr_t
-buf_dblwr_init_or_load_pages(
- pfs_os_file_t file,
- const char* path);
-
-/** Process and remove the double write buffer pages for all tablespaces. */
-void
-buf_dblwr_process();
-
-/****************************************************************//**
-frees doublewrite buffer. */
-void
-buf_dblwr_free();
-
-/** Update the doublewrite buffer on write completion. */
-void buf_dblwr_update(const buf_page_t &bpage, bool single_page);
-/****************************************************************//**
-Determines if a page number is located inside the doublewrite buffer.
-@return TRUE if the location is inside the two blocks of the
-doublewrite buffer */
-ibool
-buf_dblwr_page_inside(
-/*==================*/
- ulint page_no); /*!< in: page number */
-
-/********************************************************************//**
-Flushes possible buffered writes from the doublewrite memory buffer to disk.
-It is very important to call this function after a batch of writes
-has been posted, and also when we may have to wait for a page latch!
-Otherwise a deadlock of threads can occur. */
-void
-buf_dblwr_flush_buffered_writes();
/** Doublewrite control struct */
-struct buf_dblwr_t{
- ib_mutex_t mutex; /*!< mutex protecting the first_free
- field and write_buf */
- ulint block1; /*!< the page number of the first
- doublewrite block (64 pages) */
- ulint block2; /*!< page number of the second block */
- ulint first_free;/*!< first free position in write_buf
- measured in units of srv_page_size */
- ulint b_reserved;/*!< number of slots currently reserved
- for batch flush. */
- os_event_t b_event;/*!< event where threads wait for a
- batch flush to end;
- os_event_set() and os_event_reset()
- are protected by buf_dblwr_t::mutex */
- ulint s_reserved;/*!< number of slots currently
- reserved for single page flushes. */
- os_event_t s_event;/*!< event where threads wait for a
- single page flush slot. Protected by mutex. */
- bool batch_running;/*!< set to TRUE if currently a batch
- is being written from the doublewrite
- buffer. */
- byte* write_buf;/*!< write buffer used in writing to the
- doublewrite buffer, aligned to an
- address divisible by srv_page_size
- (which is required by Windows aio) */
-
+class buf_dblwr_t
+{
struct element
{
- /** block descriptor */
- buf_page_t *bpage;
- /** flush type */
- IORequest::flush_t flush;
+ /** asynchronous write request */
+ IORequest request;
/** payload size in bytes */
size_t size;
};
- /** buffer blocks to be written via write_buf */
- element *buf_block_arr;
+ struct slot
+ {
+ /** first free position in write_buf measured in units of
+ * srv_page_size */
+ ulint first_free;
+ /** number of slots reserved for the current write batch */
+ ulint reserved;
+ /** the doublewrite buffer, aligned to srv_page_size */
+ byte* write_buf;
+ /** buffer blocks to be written via write_buf */
+ element* buf_block_arr;
+ };
+
+ /** the page number of the first doublewrite block (block_size() pages) */
+ page_id_t block1= page_id_t(0, 0);
+ /** the page number of the second doublewrite block (block_size() pages) */
+ page_id_t block2= page_id_t(0, 0);
+
+ /** mutex protecting the data members below */
+ mysql_mutex_t mutex;
+ /** condition variable for !batch_running */
+ mysql_cond_t cond;
+ /** whether a batch is being written from the doublewrite buffer */
+ bool batch_running;
+ /** number of expected flush_buffered_writes_completed() calls */
+ unsigned flushing_buffered_writes;
+
+ slot slots[2];
+ slot *active_slot= &slots[0];
+
+ /** Initialize the doublewrite buffer data structure.
+ @param header doublewrite page header in the TRX_SYS page */
+ inline void init(const byte *header);
+
+ /** Flush possible buffered writes to persistent storage. */
+ bool flush_buffered_writes(const ulint size);
+
+public:
+ /** Create or restore the doublewrite buffer in the TRX_SYS page.
+ @return whether the operation succeeded */
+ bool create();
+ /** Free the doublewrite buffer. */
+ void close();
+
+ /** Initialize the doublewrite buffer memory structure on recovery.
+ If we are upgrading from a version before MySQL 4.1, then this
+ function performs the necessary update operations to support
+ innodb_file_per_table. If we are in a crash recovery, this function
+ loads the pages from double write buffer into memory.
+ @param file File handle
+ @param path Path name of file
+ @return DB_SUCCESS or error code */
+ dberr_t init_or_load_pages(pfs_os_file_t file, const char *path);
+
+ /** Process and remove the double write buffer pages for all tablespaces. */
+ void recover();
+
+ /** Update the doublewrite buffer on data page write completion. */
+ void write_completed();
+ /** Flush possible buffered writes to persistent storage.
+ It is very important to call this function after a batch of writes has been
+ posted, and also when we may have to wait for a page latch!
+ Otherwise a deadlock of threads can occur. */
+ void flush_buffered_writes();
+ /** Update the doublewrite buffer on write batch completion
+ @param request the completed batch write request */
+ void flush_buffered_writes_completed(const IORequest &request);
+
+ /** Size of the doublewrite block in pages */
+ uint32_t block_size() const { return FSP_EXTENT_SIZE; }
/** Schedule a page write. If the doublewrite memory buffer is full,
- buf_dblwr_flush_buffered_writes() will be invoked to make space.
- @param bpage buffer pool page to be written
- @param flush type of flush
- @param size payload size in bytes */
- void add_to_batch(buf_page_t *bpage, IORequest::flush_t flush, size_t size);
- /** Write a page to the doublewrite buffer on disk, sync it, then write
- the page to the datafile and sync the datafile. This function is used
- for single page flushes. If all the buffers allocated for single page
- flushes in the doublewrite buffer are in use we wait here for one to
- become free. We are guaranteed that a slot will become free because any
- thread that is using a slot must also release the slot before leaving
- this function.
- @param bpage buffer pool page to be written
- @param sync whether synchronous operation is requested
- @param size payload size in bytes */
- void write_single_page(buf_page_t *bpage, bool sync, size_t size);
+ flush_buffered_writes() will be invoked to make space.
+ @param request asynchronous write request
+ @param size payload size in bytes */
+ void add_to_batch(const IORequest &request, size_t size);
+
+ /** Determine whether the doublewrite buffer is initialized */
+ bool is_initialised() const
+ { return UNIV_LIKELY(block1 != page_id_t(0, 0)); }
+
+ /** @return whether a page identifier is part of the doublewrite buffer */
+ bool is_inside(const page_id_t id) const
+ {
+ if (!is_initialised())
+ return false;
+ ut_ad(block1 < block2);
+ if (id < block1)
+ return false;
+ const uint32_t size= block_size();
+ return id < block1 + size || (id >= block2 && id < block2 + size);
+ }
+
+ /** Wait for flush_buffered_writes() to be fully completed */
+ void wait_flush_buffered_writes()
+ {
+ if (is_initialised())
+ {
+ mysql_mutex_lock(&mutex);
+ while (batch_running)
+ mysql_cond_wait(&cond, &mutex);
+ mysql_mutex_unlock(&mutex);
+ }
+ }
};
-#endif
+/** The doublewrite buffer */
+extern buf_dblwr_t buf_dblwr;
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index f7f89f1a9e9..1dd0d35793b 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -31,7 +31,10 @@ Created 11/5/1995 Heikki Tuuri
#include "log0log.h"
#include "buf0types.h"
-/** Number of pages flushed through non flush_list flushes. */
+/** Number of pages flushed. Protected by buf_pool.mutex. */
+extern ulint buf_flush_page_count;
+/** Number of pages flushed via LRU. Protected by buf_pool.mutex.
+Also included in buf_flush_page_count. */
extern ulint buf_lru_flush_page_count;
/** Flag indicating if the page_cleaner is in active state. */
@@ -44,27 +47,24 @@ extern my_bool innodb_page_cleaner_disabled_debug;
#endif /* UNIV_DEBUG */
-/** Event to synchronise with the flushing. */
-extern os_event_t buf_flush_event;
+/** Remove all dirty pages belonging to a given tablespace when we are
+deleting the data file of that tablespace.
+The pages still remain a part of LRU and are evicted from
+the list as they age towards the tail of the LRU.
+@param id tablespace identifier */
+void buf_flush_remove_pages(ulint id);
-class ut_stage_alter_t;
-
-/** Handled page counters for a single flush */
-struct flush_counters_t {
- ulint flushed; /*!< number of dirty pages flushed */
- ulint evicted; /*!< number of clean pages evicted */
- ulint unzip_LRU_evicted;/*!< number of uncompressed page images
- evicted */
-};
-
-/** Remove a block from the flush list of modified blocks.
-@param[in] bpage block to be removed from the flush list */
-void buf_flush_remove(buf_page_t* bpage);
+/** Try to flush all the dirty pages that belong to a given tablespace.
+@param id tablespace identifier
+@return number dirty pages that there were for this tablespace */
+ulint buf_flush_dirty_pages(ulint id)
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Relocates a buffer control block on the flush_list.
Note that it is assumed that the contents of bpage has already been
copied to dpage. */
+ATTRIBUTE_COLD
void
buf_flush_relocate_on_flush_list(
/*=============================*/
@@ -72,12 +72,8 @@ buf_flush_relocate_on_flush_list(
buf_page_t* dpage); /*!< in/out: destination block */
/** Complete write of a file page from buf_pool.
-@param bpage written page
-@param request write request
-@param dblwr whether the doublewrite buffer was used
-@param evict whether or not to evict the page from LRU list */
-void buf_page_write_complete(buf_page_t *bpage, const IORequest &request,
- bool dblwr, bool evict);
+@param request write request */
+void buf_page_write_complete(const IORequest &request);
/** Assign the full crc32 checksum for non-compressed page.
@param[in,out] page page to be updated */
@@ -95,50 +91,23 @@ buf_flush_init_for_writing(
void* page_zip_,
bool use_full_checksum);
-/** Do flushing batch of a given type.
-NOTE: The calling thread is not allowed to own any latches on pages!
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list
-@param[in] min_n wished minimum mumber of blocks flushed
-(it is not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit in the case BUF_FLUSH_LIST all blocks whose
-oldest_modification is smaller than this should be flushed (if their number
-does not exceed min_n), otherwise ignored
-@param[out] n the number of pages which were processed is
-passed back to caller. Ignored if NULL
-@retval true if a batch was queued successfully.
-@retval false if another batch of same type was already running. */
-bool buf_flush_do_batch(bool lru, ulint min_n, lsn_t lsn_limit,
- flush_counters_t *n);
-
-/** This utility flushes dirty blocks from the end of the flush list.
-NOTE: The calling thread is not allowed to own any latches on pages!
-@param[in] min_n wished minimum mumber of blocks flushed (it is
-not guaranteed that the actual number is that big, though)
-@param[in] lsn_limit in the case BUF_FLUSH_LIST all blocks whose
-oldest_modification is smaller than this should be flushed (if their number
-does not exceed min_n), otherwise ignored
-@param[out] n_processed the number of pages which were processed is
-passed back to caller. Ignored if NULL.
-@retval true if a batch was queued successfully
-@retval false if another batch of same type was already running */
-bool buf_flush_lists(ulint min_n, lsn_t lsn_limit, ulint *n_processed);
-
-/******************************************************************//**
-This function picks up a single page from the tail of the LRU
-list, flushes it (if it is dirty), removes it from page_hash and LRU
-list and puts it on the free list. It is called from user threads when
-they are unable to find a replaceable page at the tail of the LRU
-list i.e.: when the background LRU flushing in the page_cleaner thread
-is not fast enough to keep pace with the workload.
-@return true if success. */
-bool buf_flush_single_page_from_LRU();
+/** Write out dirty blocks from buf_pool.flush_list.
+@param max_n wished maximum mumber of blocks flushed
+@param lsn buf_pool.get_oldest_modification(LSN_MAX) target (0=LRU flush)
+@return the number of processed pages
+@retval 0 if a batch of the same type (lsn==0 or lsn!=0) is already running */
+ulint buf_flush_lists(ulint max_n, lsn_t lsn);
/** Wait until a flush batch ends.
-@param[in] lru true=buf_pool.LRU; false=buf_pool.flush_list */
+@param lru true=buf_pool.LRU; false=buf_pool.flush_list */
void buf_flush_wait_batch_end(bool lru);
-/** Wait until a flush batch of the given lsn ends
-@param[in] new_oldest target oldest_modified_lsn to wait for */
-void buf_flush_wait_flushed(lsn_t new_oldest);
+/** Wait until all persistent pages are flushed up to a limit.
+@param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */
+ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn);
+/** If innodb_flush_sync=ON, initiate a furious flush.
+@param lsn buf_pool.get_oldest_modification(LSN_MAX) target */
+void buf_flush_ahead(lsn_t lsn);
+
/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it not
@@ -154,49 +123,23 @@ buf_flush_note_modification(
set of mtr's */
/** Initialize page_cleaner. */
-void buf_flush_page_cleaner_init();
+ATTRIBUTE_COLD void buf_flush_page_cleaner_init();
-/** Wait for any possible LRU flushes to complete. */
-void buf_flush_wait_LRU_batch_end();
+/** Wait for pending flushes to complete. */
+void buf_flush_wait_batch_end_acquiring_mutex(bool lru);
+
+/** Flush the buffer pool on shutdown. */
+ATTRIBUTE_COLD void buf_flush_buffer_pool();
#ifdef UNIV_DEBUG
/** Validate the flush list. */
void buf_flush_validate();
#endif /* UNIV_DEBUG */
-/********************************************************************//**
-Initialize the red-black tree to speed up insertions into the flush_list
-during recovery process. Should be called at the start of recovery
-process before any page has been read/written. */
-void
-buf_flush_init_flush_rbt(void);
-/*==========================*/
-
-/********************************************************************//**
-Frees up the red-black tree. */
-void
-buf_flush_free_flush_rbt(void);
-/*==========================*/
-
-/** Write a flushable page from buf_pool to a file.
-buf_pool.mutex must be held.
-@param bpage buffer control block
-@param flush_type type of flush
-@param space tablespace (or nullptr if not known)
-@param sync whether this is a synchronous request
- (only for flush_type=SINGLE_PAGE)
-@return whether the page was flushed and buf_pool.mutex was released */
-bool buf_flush_page(buf_page_t *bpage, IORequest::flush_t flush_type,
- fil_space_t *space, bool sync);
-
/** Synchronously flush dirty blocks.
NOTE: The calling thread is not allowed to hold any buffer page latches! */
void buf_flush_sync();
-/** Request IO burst and wake page_cleaner up.
-@param[in] lsn_limit upper limit of LSN to be flushed */
-void buf_flush_request_force(lsn_t lsn_limit);
-
#include "buf0flu.ic"
#endif
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 937cb427a47..540c14a49c9 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -34,6 +34,9 @@ Created 11/5/1995 Heikki Tuuri
struct trx_t;
struct fil_space_t;
+/** Flush this many pages in buf_LRU_get_free_block() */
+extern size_t innodb_lru_flush_size;
+
/*#######################################################################
These are low-level functions
#########################################################################*/
@@ -41,21 +44,6 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-/** Empty the flush list for all pages belonging to a tablespace.
-@param[in] id tablespace identifier
-@param[in] flush whether to write the pages to files
-@param[in] first first page to be flushed or evicted */
-void buf_LRU_flush_or_remove_pages(ulint id, bool flush, ulint first = 0);
-
-#ifdef UNIV_DEBUG
-/********************************************************************//**
-Insert a compressed block into buf_pool.zip_clean in the LRU order. */
-void
-buf_LRU_insert_zip_clean(
-/*=====================*/
- buf_page_t* bpage); /*!< in: pointer to the block in question */
-#endif /* UNIV_DEBUG */
-
/** Try to free a block. If bpage is a descriptor of a compressed-only
ROW_FORMAT=COMPRESSED page, the buf_page_t object will be freed as well.
The caller must hold buf_pool.mutex.
@@ -67,38 +55,34 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
MY_ATTRIBUTE((nonnull));
/** Try to free a replaceable block.
-@param[in] scan_all true=scan the whole LRU list,
- false=use BUF_LRU_SEARCH_SCAN_THRESHOLD
+@param limit maximum number of blocks to scan
@return true if found and freed */
-bool buf_LRU_scan_and_free_block(bool scan_all);
+bool buf_LRU_scan_and_free_block(ulint limit= ULINT_UNDEFINED);
/** @return a buffer block from the buf_pool.free list
@retval NULL if the free list is empty */
buf_block_t* buf_LRU_get_free_only();
-/** Get a free block from the buf_pool. The block is taken off the
-free list. If free list is empty, blocks are moved from the end of the
-LRU list to the free list.
+/** Get a block from the buf_pool.free list.
+If the list is empty, blocks will be moved from the end of buf_pool.LRU
+to buf_pool.free.
This function is called from a user thread when it needs a clean
block to read in a page. Note that we only ever get a block from
the free list. Even when we flush a page or find a page in LRU scan
we put it to free list to be used.
* iteration 0:
- * get a block from free list, success:done
+ * get a block from the buf_pool.free list, success:done
* if buf_pool.try_LRU_scan is set
- * scan LRU up to srv_LRU_scan_depth to find a clean block
- * the above will put the block on free list
+ * scan LRU up to 100 pages to free a clean block
* success:retry the free list
- * flush one dirty page from tail of LRU to disk
- * the above will put the block on free list
+ * flush up to innodb_lru_flush_size LRU blocks to data files
+ (until UT_LIST_GET_GEN(buf_pool.free) < innodb_lru_scan_depth)
+ * on buf_page_write_complete() the blocks will put on buf_pool.free list
* success: retry the free list
-* iteration 1:
- * same as iteration 0 except:
- * scan whole LRU list
- * scan LRU list even if buf_pool.try_LRU_scan is not set
-* iteration > 1:
- * same as iteration 1 but sleep 10ms
+* subsequent iterations: same as iteration 0 except:
+ * scan whole LRU list
+ * scan LRU list even if buf_pool.try_LRU_scan is not set
@param have_mutex whether buf_pool.mutex is already being held
@return the free control block, in state BUF_BLOCK_MEMORY */
diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
index f4d1560862a..87c6b5d7e75 100644
--- a/storage/innobase/include/buf0rea.h
+++ b/storage/innobase/include/buf0rea.h
@@ -46,11 +46,13 @@ dberr_t buf_read_page(const page_id_t page_id, ulint zip_size);
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread.
+@param[in,out] space tablespace
@param[in] page_id page id
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] sync true if synchronous aio is desired */
-void
-buf_read_page_background(const page_id_t page_id, ulint zip_size, bool sync);
+void buf_read_page_background(fil_space_t *space, const page_id_t page_id,
+ ulint zip_size, bool sync)
+ MY_ATTRIBUTE((nonnull));
/** Applies a random read-ahead in buf_pool if there are at least a threshold
value of accessed pages from the random read-ahead area. Does not read any
@@ -101,19 +103,11 @@ ulint
buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf);
/** Issues read requests for pages which recovery wants to read in.
-@param[in] sync true if the caller wants this function to wait
-for the highest address page to get read in, before this function returns
@param[in] space_id tablespace id
@param[in] page_nos array of page numbers to read, with the
highest page number the last in the array
-@param[in] n_stored number of page numbers in the array */
-
-void
-buf_read_recv_pages(
- bool sync,
- ulint space_id,
- const ulint* page_nos,
- ulint n_stored);
+@param[in] n number of page numbers in the array */
+void buf_read_recv_pages(ulint space_id, const uint32_t* page_nos, ulint n);
/** @name Modes used in read-ahead @{ */
/** read only pages belonging to the insert buffer tree */
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index 55bd2ac3a5a..ba1e2e5eaa6 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -27,8 +27,7 @@ Created 11/17/1995 Heikki Tuuri
#ifndef buf0types_h
#define buf0types_h
-#include "os0event.h"
-#include "ut0ut.h"
+#include "univ.i"
/** Buffer page (uncompressed or compressed) */
class buf_page_t;
@@ -38,8 +37,6 @@ struct buf_block_t;
struct buf_pool_stat_t;
/** Buffer pool buddy statistics struct */
struct buf_buddy_stat_t;
-/** Doublewrite memory struct */
-struct buf_dblwr_t;
/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
@@ -125,10 +122,9 @@ public:
/** Constructor from (space, page_no).
@param[in] space tablespace id
@param[in] page_no page number */
- page_id_t(ulint space, ulint page_no) : m_id(uint64_t{space} << 32 | page_no)
+ page_id_t(ulint space, uint32_t page_no) : m_id(uint64_t{space} << 32 | page_no)
{
ut_ad(space <= 0xFFFFFFFFU);
- ut_ad(page_no <= 0xFFFFFFFFU);
}
page_id_t(uint64_t id) : m_id(id) {}
@@ -170,9 +166,8 @@ public:
/** Reset the page number only.
@param[in] page_no page number */
- void set_page_no(ulint page_no)
+ void set_page_no(uint32_t page_no)
{
- ut_ad(page_no <= 0xFFFFFFFFU);
m_id= (m_id & ~uint64_t{0} << 32) | page_no;
}
@@ -194,10 +189,6 @@ extern const byte field_ref_zero[UNIV_PAGE_SIZE_MAX];
#include "sync0rw.h"
#include "rw_lock.h"
-typedef ib_mutex_t BufPoolMutex;
-typedef ib_mutex_t FlushListMutex;
-typedef rw_lock_t BPageLock;
-
class page_hash_latch : public rw_lock
{
public:
diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h
index ae017932b9f..3aea41b0bb8 100644
--- a/storage/innobase/include/dict0defrag_bg.h
+++ b/storage/innobase/include/dict0defrag_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-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
@@ -27,8 +27,6 @@ Created 25/08/2016 Jan Lindström
#ifndef dict0defrag_bg_h
#define dict0defrag_bg_h
-#include "os0event.h"
-#include "os0thread.h"
#include "dict0types.h"
/** Indices whose defrag stats need to be saved to persistent storage.*/
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index b5319d51c9a..276252e625c 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1280,7 +1280,7 @@ UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- dict_index_t* index) /*!< in: index */
+ const dict_index_t* index) /*!< in: index */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************//**
Returns free space reserved for future updates of records. This is
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 4a006471c37..eda639ba7c1 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -914,7 +914,7 @@ UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- dict_index_t* index) /*!< in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 0c42c5ffe6f..1ad2517c8fb 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -298,19 +298,17 @@ parent table will fail, and user has to drop excessive foreign constraint
before proceeds. */
#define FK_MAX_CASCADE_DEL 15
-/** Creates a table memory object.
-@param[in] name table name
-@param[in] space tablespace
-@param[in] n_cols total number of columns including virtual and
- non-virtual columns
-@param[in] n_v_cols number of virtual columns
-@param[in] flags table flags
-@param[in] flags2 table flags2
-@param[in] init_stats_latch whether to init the stats latch
+/** Create a table memory object.
+@param name table name
+@param space tablespace
+@param n_cols total number of columns (both virtual and non-virtual)
+@param n_v_cols number of virtual columns
+@param flags table flags
+@param flags2 table flags2
@return own: table object */
dict_table_t *dict_mem_table_create(const char *name, fil_space_t *space,
ulint n_cols, ulint n_v_cols, ulint flags,
- ulint flags2, bool init_stats_latch= true);
+ ulint flags2);
/****************************************************************/ /**
Free a table memory object. */
void
@@ -766,9 +764,6 @@ struct dict_v_col_t{
/** column pos in table */
unsigned v_pos:10;
- /** number of indexes */
- unsigned n_v_indexes:12;
-
/** Virtual index list, and column position in the index */
std::forward_list<dict_v_idx_t, ut_allocator<dict_v_idx_t> >
v_indexes;
@@ -777,21 +772,17 @@ struct dict_v_col_t{
@param index index to be detached from */
void detach(const dict_index_t &index)
{
- if (!n_v_indexes) return;
+ if (v_indexes.empty()) return;
auto i= v_indexes.before_begin();
- ut_d(unsigned n= 0);
do {
auto prev = i++;
if (i == v_indexes.end())
{
- ut_ad(n == n_v_indexes);
return;
}
- ut_ad(++n <= n_v_indexes);
if (i->index == &index)
{
v_indexes.erase_after(prev);
- n_v_indexes--;
return;
}
}
@@ -1125,7 +1116,7 @@ public:
when InnoDB was started up */
zip_pad_info_t zip_pad;/*!< Information about state of
compression failures and successes */
- rw_lock_t lock; /*!< read-write lock protecting the
+ mutable rw_lock_t lock; /*!< read-write lock protecting the
upper levels of the index tree */
/** Determine if the index has been committed to the
@@ -1450,6 +1441,10 @@ struct dict_foreign_t{
dict_vcol_set* v_cols; /*!< set of virtual columns affected
by foreign key constraint. */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
@@ -1809,6 +1804,13 @@ struct dict_table_t {
return(UNIV_LIKELY(!file_unreadable));
}
+ /** @return whether the table is accessible */
+ bool is_accessible() const
+ {
+ return UNIV_LIKELY(is_readable() && !corrupted && space)
+ && !space->is_stopping();
+ }
+
/** Check if a table name contains the string "/#sql"
which denotes temporary or intermediate tables in MariaDB. */
static bool is_temporary_name(const char* name)
@@ -2133,22 +2135,8 @@ public:
/*!< set of foreign key constraints which refer to this table */
dict_foreign_set referenced_set;
- /** Statistics for query optimization. @{ */
-
- /** This latch protects:
- dict_table_t::stat_initialized,
- dict_table_t::stat_n_rows (*),
- dict_table_t::stat_clustered_index_size,
- dict_table_t::stat_sum_of_other_index_sizes,
- dict_table_t::stat_modified_counter (*),
- dict_table_t::indexes*::stat_n_diff_key_vals[],
- dict_table_t::indexes*::stat_index_size,
- dict_table_t::indexes*::stat_n_leaf_pages.
- (*) Those are not always protected for
- performance reasons. */
- rw_lock_t stats_latch;
-
- bool stats_latch_inited= false;
+ /** Statistics for query optimization. Mostly protected by
+ dict_sys.mutex. @{ */
/** TRUE if statistics have been calculated the first time after
database startup or table creation. */
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 0b8c57a5eba..4972efe8961 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -75,7 +75,7 @@ dict_stats_is_persistent_enabled(const dict_table_t* table)
+ dict_stats_update(DICT_STATS_RECALC_TRANSIENT) on a table that has
just been PS-enabled.
This is acceptable. Avoiding this would mean that we would have to
- protect the ::stat_persistent with dict_table_t::stats_latch like the
+ protect the stat_persistent with dict_sys.mutex like the
other ::stat_ members which would be too big performance penalty,
especially when this function is called from
dict_stats_update_if_needed(). */
@@ -178,10 +178,7 @@ dict_stats_deinit(
ut_a(table->get_ref_count() == 0);
- rw_lock_x_lock(&table->stats_latch);
-
if (!table->stat_initialized) {
- rw_lock_x_unlock(&table->stats_latch);
return;
}
@@ -221,6 +218,4 @@ dict_stats_deinit(
sizeof(index->stat_n_leaf_pages));
}
#endif /* HAVE_valgrind */
-
- rw_lock_x_unlock(&table->stats_latch);
}
diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h
index 62746e31021..b210a2ec357 100644
--- a/storage/innobase/include/dict0stats_bg.h
+++ b/storage/innobase/include/dict0stats_bg.h
@@ -28,10 +28,8 @@ Created Apr 26, 2012 Vasil Dimov
#define dict0stats_bg_h
#include "dict0types.h"
-#include "os0event.h"
#include "os0thread.h"
-
#ifdef HAVE_PSI_INTERFACE
extern mysql_pfs_key_t dict_stats_recalc_pool_mutex_key;
#endif /* HAVE_PSI_INTERFACE */
diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h
index 62714b88679..49567a49a78 100644
--- a/storage/innobase/include/fil0crypt.h
+++ b/storage/innobase/include/fil0crypt.h
@@ -85,8 +85,8 @@ struct fil_space_rotate_state_t
{
time_t start_time; /*!< time when rotation started */
ulint active_threads; /*!< active threads in space */
- ulint next_offset; /*!< next "free" offset */
- ulint max_offset; /*!< max offset needing to be rotated */
+ uint32_t next_offset; /*!< next "free" offset */
+ uint32_t max_offset; /*!< max offset needing to be rotated */
uint min_key_version_found; /*!< min key version found but not
rotated */
lsn_t end_lsn; /*!< max lsn created when rotating this
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 96cf0a45b65..e645ce31232 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -33,6 +33,7 @@ Created 10/25/1995 Heikki Tuuri
#ifndef UNIV_INNOCHECKSUM
+#include "buf0dblwr.h"
#include "hash0hash.h"
#include "log0recv.h"
#include "dict0types.h"
@@ -92,7 +93,6 @@ inline bool srv_is_undo_tablespace(ulint space_id)
space_id < srv_undo_space_id_start + srv_undo_tablespaces_open;
}
-extern struct buf_dblwr_t* buf_dblwr;
class page_id_t;
/** Structure containing encryption specification */
@@ -313,13 +313,33 @@ new_range:
/** Tablespace or log data space */
#ifndef UNIV_INNOCHECKSUM
-struct fil_space_t : ilist_node<unflushed_spaces_tag_t>,
- ilist_node<rotation_list_tag_t>
+struct fil_io_t
+{
+ /** error code */
+ dberr_t err;
+ /** file; node->space->release() must follow IORequestRead call */
+ fil_node_t *node;
+};
+
+/** Tablespace encryption mode */
+enum fil_encryption_t
+{
+ /** Encrypted if innodb_encrypt_tables=ON (srv_encrypt_tables) */
+ FIL_ENCRYPTION_DEFAULT,
+ /** Encrypted */
+ FIL_ENCRYPTION_ON,
+ /** Not encrypted */
+ FIL_ENCRYPTION_OFF
+};
+
+struct fil_space_t final :
+ ilist_node<unflushed_spaces_tag_t>, ilist_node<rotation_list_tag_t>
#else
-struct fil_space_t
+struct fil_space_t final
#endif
{
#ifndef UNIV_INNOCHECKSUM
+ friend fil_node_t;
ulint id; /*!< space id */
hash_node_t hash; /*!< hash chain node */
char* name; /*!< Tablespace name */
@@ -335,50 +355,41 @@ struct fil_space_t
fil_type_t purpose;/*!< purpose */
UT_LIST_BASE_NODE_T(fil_node_t) chain;
/*!< base node for the file chain */
- ulint size; /*!< tablespace file size in pages;
+ uint32_t size; /*!< tablespace file size in pages;
0 if not known yet */
- ulint size_in_header;
+ uint32_t size_in_header;
/* FSP_SIZE in the tablespace header;
0 if not known yet */
- ulint free_len;
+ uint32_t free_len;
/*!< length of the FSP_FREE list */
- ulint free_limit;
+ uint32_t free_limit;
/*!< contents of FSP_FREE_LIMIT */
- ulint recv_size;
+ uint32_t recv_size;
/*!< 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 */
- Atomic_relaxed<ulint> committed_size;
- ulint n_reserved_extents;
+ uint32_t n_reserved_extents;
/*!< number of reserved free extents for
ongoing operations like B-tree page split */
- ulint n_pending_flushes; /*!< this is positive when flushing
- the tablespace to disk; dropping of the
- tablespace is forbidden if this is positive */
private:
- /** Number of pending buffer pool operations accessing the
- tablespace without holding a table lock or dict_operation_lock
- S-latch that would prevent the table (and tablespace) from being
- dropped. An example is encryption key rotation.
-
- The tablespace cannot be dropped while this is nonzero, or while
- fil_node_t::n_pending is nonzero.
-
- The most significant bit contains the STOP_NEW_OPS flag. */
- Atomic_relaxed<size_t> n_pending_ops;
-
- /** Flag in n_pending_ops that indicates that the tablespace is being
+ /** the committed size of the tablespace in pages */
+ Atomic_relaxed<uint32_t> committed_size;
+ /** Number of pending operations on the file.
+ The tablespace cannot be freed while (n_pending & PENDING) != 0. */
+ std::atomic<uint32_t> n_pending;
+ /** Flag in n_pending that indicates that the tablespace is being
deleted, and no further operations should be performed */
- static const size_t STOP_NEW_OPS= ~(~size_t(0) >> 1);
+ static constexpr uint32_t STOPPING= 1U << 31;
+ /** Flag in n_pending that indicates that the tablespace is a candidate
+ for being closed, and fil_node_t::is_open() can only be trusted after
+ acquiring fil_system.mutex and resetting the flag */
+ static constexpr uint32_t CLOSING= 1U << 30;
+ /** Flag in n_pending that indicates that the tablespace needs fsync().
+ This must be the least significant flag bit; @see release_flush() */
+ static constexpr uint32_t NEEDS_FSYNC= 1U << 29;
+ /** The reference count */
+ static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC);
public:
- /** Number of pending block read or write operations
- (when a write is imminent or a read has recently completed).
- The tablespace object cannot be freed while this is nonzero,
- but it can be detached from fil_system.
- Note that fil_node_t::n_pending tracks actual pending I/O requests.
- Protected by fil_system.mutex and std::atomic. */
- std::atomic<ulint> n_pending_ios;
rw_lock_t latch; /*!< latch protecting the file space storage
allocation */
UT_LIST_NODE_T(fil_space_t) named_spaces;
@@ -415,22 +426,13 @@ public:
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
- /** 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
+ /** @return whether doublewrite buffering is needed */
+ bool use_doublewrite() const
{
- const ulint limit= committed_size;
- return limit > offset ? offset : limit;
+ return !atomic_write_supported && srv_use_doublewrite_buf &&
+ buf_dblwr.is_initialised();
}
- /** @return whether doublewrite buffering is needed */
- bool use_doublewrite() const
- {
- return !atomic_write_supported
- && srv_use_doublewrite_buf && buf_dblwr;
- }
-
/** Append a file to the chain of files of a space.
@param[in] name file name of a file that is not open
@param[in] handle file handle, or OS_FILE_CLOSED
@@ -438,11 +440,11 @@ public:
@param[in] is_raw whether this is a raw device
@param[in] atomic_write true if atomic write could be enabled
@param[in] max_pages maximum number of pages in file,
- or ULINT_MAX for unlimited
+ or UINT32_MAX for unlimited
@return file object */
fil_node_t* add(const char* name, pfs_os_file_t handle,
- ulint size, bool is_raw, bool atomic_write,
- ulint max_pages = ULINT_MAX);
+ uint32_t size, bool is_raw, bool atomic_write,
+ uint32_t max_pages = UINT32_MAX);
#ifdef UNIV_DEBUG
/** Assert that the mini-transaction is compatible with
updating an allocation bitmap page.
@@ -454,7 +456,7 @@ public:
@param[in] n_free_now current number of free extents
@param[in] n_to_reserve number of extents to reserve
@return whether the reservation succeeded */
- bool reserve_free_extents(ulint n_free_now, ulint n_to_reserve)
+ bool reserve_free_extents(uint32_t n_free_now, uint32_t n_to_reserve)
{
ut_ad(rw_lock_own(&latch, RW_LOCK_X));
if (n_reserved_extents + n_to_reserve > n_free_now) {
@@ -467,7 +469,7 @@ public:
/** Release the reserved free extents.
@param[in] n_reserved number of reserved extents */
- void release_free_extents(ulint n_reserved)
+ void release_free_extents(uint32_t n_reserved)
{
if (!n_reserved) return;
ut_ad(rw_lock_own(&latch, RW_LOCK_X));
@@ -485,78 +487,107 @@ public:
dberr_t rename(const char* name, const char* path, bool log,
bool replace = false);
- /** Note that the tablespace has been imported.
- Initially, purpose=FIL_TYPE_IMPORT so that no redo log is
- written while the space ID is being updated in each page. */
- inline void set_imported();
-
- /** @return whether the storage device is rotational (HDD, not SSD) */
- inline bool is_rotational() const;
+ /** Note that the tablespace has been imported.
+ Initially, purpose=FIL_TYPE_IMPORT so that no redo log is
+ written while the space ID is being updated in each page. */
+ inline void set_imported();
- /** Open each file. Only invoked on fil_system.temp_space.
- @return whether all files were opened */
- bool open();
- /** Close each file. Only invoked on fil_system.temp_space. */
- void close();
+ /** @return whether the storage device is rotational (HDD, not SSD) */
+ inline bool is_rotational() const;
- /** @return whether the tablespace is about to be dropped */
- bool is_stopping() const { return n_pending_ops & STOP_NEW_OPS; }
-
- /** @return number of references being held */
- size_t referenced() const { return n_pending_ops & ~STOP_NEW_OPS; }
+ /** Open each file. Never invoked on .ibd files.
+ @param create_new_db whether to skip the call to fil_node_t::read_page0()
+ @return whether all files were opened */
+ bool open(bool create_new_db);
+ /** Close each file. Only invoked on fil_system.temp_space. */
+ void close();
/** Note that operations on the tablespace must stop or can resume */
- void set_stopping(bool stopping)
+ inline void set_stopping(bool stopping);
+
+private:
+ MY_ATTRIBUTE((warn_unused_result))
+ /** Try to acquire a tablespace reference.
+ @return the old reference count (if STOPPING is set, it was not acquired) */
+ uint32_t acquire_low()
{
- ut_d(auto n=) n_pending_ops.fetch_xor(STOP_NEW_OPS);
- ut_ad(!(n & STOP_NEW_OPS) == stopping);
+ uint32_t n= 0;
+ while (!n_pending.compare_exchange_strong(n, n + 1,
+ std::memory_order_acquire,
+ std::memory_order_relaxed) &&
+ !(n & STOPPING));
+ return n;
}
-
+public:
MY_ATTRIBUTE((warn_unused_result))
/** @return whether a tablespace reference was successfully acquired */
+ inline bool acquire_if_not_stopped(bool have_mutex= false);
+
+ MY_ATTRIBUTE((warn_unused_result))
+ /** Acquire a tablespace reference for I/O.
+ @return whether the file is usable */
bool acquire()
{
- size_t n= 0;
- while (!n_pending_ops.compare_exchange_strong(n, n + 1,
- std::memory_order_acquire,
- std::memory_order_relaxed))
- if (UNIV_UNLIKELY(n & STOP_NEW_OPS))
- return false;
- return true;
+ uint32_t n= acquire_low();
+ if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
+ return true;
+ return UNIV_LIKELY(!(n & STOPPING)) && prepare();
}
+
+ /** Acquire another tablespace reference for I/O. */
+ inline void reacquire();
+
/** Release a tablespace reference.
@return whether this was the last reference */
bool release()
{
- auto n= n_pending_ops.fetch_sub(1);
- ut_ad(n & ~STOP_NEW_OPS);
- return (n & ~STOP_NEW_OPS) == 1;
+ uint32_t n= n_pending.fetch_sub(1, std::memory_order_release);
+ ut_ad(n & PENDING);
+ return (n & PENDING) == 1;
}
- /** Acquire a tablespace reference for I/O. */
- void acquire_for_io() { n_pending_ios++; }
- /** Release a tablespace reference for I/O. */
- void release_for_io() { ut_d(auto n=) n_pending_ios--; ut_ad(n); }
- /** @return whether I/O is pending */
- bool pending_io() const { return n_pending_ios; }
-
- /** @return whether the tablespace file can be closed and reopened */
- bool belongs_in_lru() const
+
+ /** Clear the NEEDS_FSYNC flag */
+ void clear_flush()
+ { n_pending.fetch_and(~NEEDS_FSYNC, std::memory_order_release); }
+
+private:
+ /** @return pending operations (and flags) */
+ uint32_t pending()const { return n_pending.load(std::memory_order_acquire); }
+public:
+ /** @return whether close() of the file handle has been requested */
+ bool is_closing() const { return pending() & CLOSING; }
+ /** @return whether the tablespace is going to be dropped */
+ bool is_stopping() const { return pending() & STOPPING; }
+ /** @return number of pending operations */
+ bool is_ready_to_close() const
+ { return (pending() & (PENDING | CLOSING)) == CLOSING; }
+ /** @return whether fsync() or similar is needed */
+ bool needs_flush() const { return pending() & NEEDS_FSYNC; }
+ /** @return whether fsync() or similar is needed, and the tablespace is
+ not being dropped */
+ bool needs_flush_not_stopping() const
+ { return (pending() & (NEEDS_FSYNC | STOPPING)) == NEEDS_FSYNC; }
+
+ uint32_t referenced() const { return pending() & PENDING; }
+private:
+ MY_ATTRIBUTE((warn_unused_result))
+ /** Prepare to close the file handle.
+ @return number of pending operations, possibly with NEEDS_FSYNC flag */
+ uint32_t set_closing()
{
- switch (purpose) {
- case FIL_TYPE_TEMPORARY:
- ut_ad(id == SRV_TMP_SPACE_ID);
- return false;
- case FIL_TYPE_IMPORT:
- ut_ad(id != SRV_TMP_SPACE_ID);
- return true;
- case FIL_TYPE_TABLESPACE:
- ut_ad(id != SRV_TMP_SPACE_ID);
- return id && !srv_is_undo_tablespace(id);
- }
- ut_ad(0);
- return false;
+ return n_pending.fetch_or(CLOSING, std::memory_order_acquire) &
+ (PENDING | NEEDS_FSYNC);
}
+public:
+ /** Try to close a file to adhere to the innodb_open_files limit.
+ @param print_info whether to diagnose why a file cannot be closed
+ @return whether a file was closed */
+ static bool try_to_close(bool print_info);
+
+ /** Close all tablespace files at shutdown */
+ static void close_all();
+
/** @return last_freed_lsn */
lsn_t get_last_freed_lsn() { return last_freed_lsn; }
/** Update last_freed_lsn */
@@ -566,6 +597,23 @@ public:
last_freed_lsn= lsn;
}
+ /** Note that the file will need fsync().
+ @return whether this needs to be added to fil_system.unflushed_spaces */
+ bool set_needs_flush()
+ {
+ uint32_t n= 1;
+ while (!n_pending.compare_exchange_strong(n, n | NEEDS_FSYNC,
+ std::memory_order_acquire,
+ std::memory_order_relaxed))
+ {
+ ut_ad(n & PENDING);
+ if (n & (NEEDS_FSYNC | STOPPING))
+ return false;
+ }
+
+ return true;
+ }
+
/** Clear all freed ranges for undo tablespace when InnoDB
encounters TRIM redo log record */
void clear_freed_ranges()
@@ -844,12 +892,33 @@ public:
}
#ifndef UNIV_INNOCHECKSUM
+ MY_ATTRIBUTE((warn_unused_result))
+ /** Create a tablespace in fil_system.
+ @param name tablespace name
+ @param id tablespace identifier
+ @param flags tablespace flags
+ @param purpose tablespace purpose
+ @param crypt_data encryption information
+ @param mode encryption mode
+ @return pointer to created tablespace, to be filled in with add()
+ @retval nullptr on failure (such as when the same tablespace exists) */
+ static fil_space_t *create(const char *name, ulint id, ulint flags,
+ fil_type_t purpose, fil_space_crypt_t *crypt_data,
+ fil_encryption_t mode= FIL_ENCRYPTION_DEFAULT);
+
+ MY_ATTRIBUTE((warn_unused_result))
+ /** Acquire a tablespace reference.
+ @param id tablespace identifier
+ @return tablespace
+ @retval nullptr if the tablespace is missing or inaccessible */
+ static fil_space_t *get(ulint id);
+
/** Add/remove the free page in the freed ranges list.
@param[in] offset page number to be added
@param[in] free true if page to be freed */
void free_page(uint32_t offset, bool add=true)
{
- std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
+ std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
if (add)
return freed_ranges.add_value(offset);
@@ -862,7 +931,7 @@ public:
/** Add the range of freed pages */
void add_free_ranges(range_set ranges)
{
- std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
+ std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
freed_ranges= std::move(ranges);
}
@@ -872,8 +941,59 @@ public:
std::lock_guard<std::mutex> freed_lock(freed_range_mutex);
freed_ranges.add_range(range);
}
-#endif /*!UNIV_INNOCHECKSUM */
+ /** Set the tablespace size in pages */
+ void set_sizes(uint32_t s)
+ {
+ ut_ad(id ? !size : (size >= s));
+ size= s; committed_size= s;
+ }
+
+ /** Update committed_size in mtr_t::commit() */
+ void set_committed_size()
+ {
+ ut_ad(rw_lock_own(&latch, RW_LOCK_X));
+ committed_size= size;
+ }
+
+ /** @return the last persisted page number */
+ uint32_t last_page_number() const { return committed_size - 1; }
+
+ /** @return the size in pages (0 if unreadable) */
+ inline uint32_t get_size();
+
+ /** Read or write data.
+ @param type I/O context
+ @param offset offset in bytes
+ @param len number of bytes
+ @param buf the data to be read or written
+ @param bpage buffer block (for type.is_async() completion callback)
+ @return status and file descriptor */
+ fil_io_t io(const IORequest &type, os_offset_t offset, size_t len,
+ void *buf, buf_page_t *bpage= nullptr);
+ /** Flush pending writes from the file system cache to the file. */
+ inline void flush();
+ /** Flush pending writes from the file system cache to the file. */
+ void flush_low();
+
+ /** Read the first page of a data file.
+ @return whether the page was found valid */
+ bool read_page0();
+
+ /** Determine the next tablespace for encryption key rotation.
+ @param space current tablespace (nullptr to start from the beginning)
+ @param recheck whether the removal condition needs to be rechecked after
+ encryption parameters were changed
+ @param encrypt expected state of innodb_encrypt_tables
+ @return the next tablespace
+ @retval nullptr upon reaching the end of the iteration */
+ static inline fil_space_t *next(fil_space_t *space, bool recheck,
+ bool encrypt);
+
+private:
+ /** @return whether the file is usable for io() */
+ ATTRIBUTE_COLD bool prepare(bool have_mutex= false);
+#endif /*!UNIV_INNOCHECKSUM */
};
#ifndef UNIV_INNOCHECKSUM
@@ -881,7 +1001,8 @@ public:
#define FIL_SPACE_MAGIC_N 89472
/** File node of a tablespace or the log data space */
-struct fil_node_t {
+struct fil_node_t final
+{
/** tablespace containing this file */
fil_space_t* space;
/** file name; protected by fil_system.mutex and log_sys.mutex. */
@@ -895,24 +1016,16 @@ struct fil_node_t {
/** size of the file in database pages (0 if not known yet);
the possible last incomplete megabyte may be ignored
if space->id == 0 */
- ulint size;
+ uint32_t size;
/** initial size of the file in database pages;
FIL_IBD_FILE_INITIAL_SIZE by default */
- ulint init_size;
+ uint32_t init_size;
/** maximum size of the file in database pages (0 if unlimited) */
- ulint max_size;
- /** count of pending i/o's; is_open must be true if nonzero */
- ulint n_pending;
- /** count of pending flushes; is_open must be true if nonzero */
- ulint n_pending_flushes;
+ uint32_t max_size;
/** whether the file is currently being extended */
- bool being_extended;
- /** whether this file had writes after lasy fsync() */
- bool needs_flush;
+ Atomic_relaxed<bool> being_extended;
/** link to other files in this tablespace */
UT_LIST_NODE_T(fil_node_t) chain;
- /** link to the fil_system.LRU list (keeping track of open files) */
- UT_LIST_NODE_T(fil_node_t) LRU;
/** whether this file could use atomic write (data file) */
bool atomic_write;
@@ -930,9 +1043,8 @@ struct fil_node_t {
}
/** Read the first page of a data file.
- @param[in] first whether this is the very first read
@return whether the page was found valid */
- bool read_page0(bool first);
+ bool read_page0();
/** Determine some file metadata when creating or reading the file.
@param file the file that is being created, or OS_FILE_CLOSED */
@@ -949,10 +1061,10 @@ struct fil_node_t {
/** Prepare to free a file from fil_system.
@param detach_handle whether to detach instead of closing a handle
@return detached handle or OS_FILE_CLOSED */
- pfs_os_file_t close_to_free(bool detach_handle= false);
+ inline pfs_os_file_t close_to_free(bool detach_handle= false);
- /** Update the data structures on I/O completion */
- inline void complete_io(bool write= false);
+ /** Update the data structures on write completion */
+ inline void complete_write();
private:
/** Does stuff common for close() and detach() */
@@ -964,20 +1076,18 @@ private:
inline void fil_space_t::set_imported()
{
- ut_ad(purpose == FIL_TYPE_IMPORT);
- purpose = FIL_TYPE_TABLESPACE;
- UT_LIST_GET_FIRST(chain)->find_metadata();
+ ut_ad(purpose == FIL_TYPE_IMPORT);
+ purpose= FIL_TYPE_TABLESPACE;
+ UT_LIST_GET_FIRST(chain)->find_metadata();
}
inline bool fil_space_t::is_rotational() const
{
- for (const fil_node_t* node = UT_LIST_GET_FIRST(chain);
- node != NULL; node = UT_LIST_GET_NEXT(chain, node)) {
- if (!node->on_ssd) {
- return true;
- }
- }
- return false;
+ for (const fil_node_t *node= UT_LIST_GET_FIRST(chain); node;
+ node= UT_LIST_GET_NEXT(chain, node))
+ if (!node->on_ssd)
+ return true;
+ return false;
}
/** Common InnoDB file extensions */
@@ -1188,16 +1298,6 @@ index */
#define fil_page_index_page_check(page) \
fil_page_type_is_index(fil_page_get_type(page))
-/** Enum values for encryption table option */
-enum fil_encryption_t {
- /** Encrypted if innodb_encrypt_tables=ON (srv_encrypt_tables) */
- FIL_ENCRYPTION_DEFAULT,
- /** Encrypted */
- FIL_ENCRYPTION_ON,
- /** Not encrypted */
- FIL_ENCRYPTION_OFF
-};
-
/** Get the file page type.
@param[in] page file page
@return page type */
@@ -1209,15 +1309,14 @@ inline uint16_t fil_page_get_type(const byte *page)
#ifndef UNIV_INNOCHECKSUM
/** Number of pending tablespace flushes */
-extern ulint fil_n_pending_tablespace_flushes;
+extern Atomic_counter<ulint> fil_n_pending_tablespace_flushes;
/** Look up a tablespace.
The caller should hold an InnoDB table lock or a MDL that prevents
the tablespace from being dropped during the operation,
or the caller should be in single-threaded crash recovery mode
(no user connections that could drop tablespaces).
-If this is not the case, fil_space_acquire() and fil_space_t::release()
-should be used instead.
+Normally, fil_space_t::get() should be used instead.
@param[in] id tablespace ID
@return tablespace, or NULL if not found */
fil_space_t*
@@ -1236,7 +1335,6 @@ struct fil_system_t {
*/
fil_system_t(): m_initialised(false)
{
- UT_LIST_INIT(LRU, &fil_node_t::LRU);
UT_LIST_INIT(space_list, &fil_space_t::space_list);
UT_LIST_INIT(named_spaces, &fil_space_t::named_spaces);
}
@@ -1284,30 +1382,19 @@ public:
fil_space_t* temp_space; /*!< The innodb_temporary tablespace */
/** Map of fil_space_t::id to fil_space_t* */
hash_table_t spaces;
- UT_LIST_BASE_NODE_T(fil_node_t) LRU;
- /*!< base node for the LRU list of the
- most recently used open files with no
- pending i/o's; if we start an i/o on
- the file, we first remove it from this
- list, and return it to the start of
- the list when the i/o ends;
- log files and the system tablespace are
- not put to this list: they are opened
- after the startup, and kept open until
- shutdown */
- sized_ilist<fil_space_t, unflushed_spaces_tag_t> unflushed_spaces;
- /*!< list of those
- tablespaces whose files contain
- unflushed writes; those spaces have
- at least one file node where
- needs_flush == true */
- ulint n_open; /*!< number of files currently open */
+ /** tablespaces for which fil_space_t::needs_flush() holds */
+ sized_ilist<fil_space_t, unflushed_spaces_tag_t> unflushed_spaces;
+ /** number of currently open files; protected by mutex */
+ ulint n_open;
ulint max_assigned_id;/*!< maximum space id in the existing
tables, or assigned during the time
mysqld has been up; at an InnoDB
startup we scan the data dictionary
and set here the maximum of the
space id's of the tables there */
+ /** nonzero if fil_node_open_file_low() should avoid moving the tablespace
+ to the end of space_list, for FIFO policy of try_to_close() */
+ ulint freeze_space_list;
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
/*!< list of all file spaces */
UT_LIST_BASE_NODE_T(fil_space_t) named_spaces;
@@ -1321,16 +1408,10 @@ public:
key rotation.*/
bool space_id_reuse_warned;
- /*!< whether fil_space_create()
+ /*!< whether fil_space_t::create()
has issued a warning about
potential space_id reuse */
- /** Trigger a call to fil_node_t::read_page0()
- @param[in] id tablespace identifier
- @return tablespace
- @retval NULL if the tablespace does not exist or cannot be read */
- fil_space_t* read_page0(ulint id);
-
/** Return the next tablespace from rotation_list.
@param space previous tablespace (NULL to start from the start)
@param recheck whether the removal condition needs to be rechecked after
@@ -1345,63 +1426,60 @@ public:
/** The tablespace memory cache. */
extern fil_system_t fil_system;
-/** Update the data structures on I/O completion */
-inline void fil_node_t::complete_io(bool write)
+inline void fil_space_t::reacquire()
+{
+ ut_d(uint32_t n=) n_pending.fetch_add(1, std::memory_order_relaxed);
+ ut_d(if (mutex_own(&fil_system.mutex)) return);
+ ut_ad(n & PENDING);
+ ut_ad(UT_LIST_GET_FIRST(chain)->is_open());
+}
+
+inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
+{
+ ut_ad(mutex_own(&fil_system.mutex) == have_mutex);
+ const uint32_t n= acquire_low();
+ if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
+ return true;
+ return UNIV_LIKELY(!(n & CLOSING)) || prepare(have_mutex);
+}
+
+/** Note that operations on the tablespace must stop or can resume */
+inline void fil_space_t::set_stopping(bool stopping)
{
ut_ad(mutex_own(&fil_system.mutex));
+ ut_d(auto n=) n_pending.fetch_xor(STOPPING, std::memory_order_relaxed);
+ ut_ad(!(n & STOPPING) == stopping);
+}
- if (write)
+/** Flush pending writes from the file system cache to the file. */
+inline void fil_space_t::flush()
+{
+ ut_ad(!mutex_own(&fil_system.mutex));
+
+ ut_ad(purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT);
+ if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
{
- if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
- {
- /* We don't need to keep track of unflushed changes as user has
- explicitly disabled buffering. */
- ut_ad(!space->is_in_unflushed_spaces);
- ut_ad(!needs_flush);
- }
- else if (!space->is_stopping())
- {
- needs_flush= true;
- if (!space->is_in_unflushed_spaces)
- {
- space->is_in_unflushed_spaces= true;
- fil_system.unflushed_spaces.push_front(*space);
- }
- }
+ ut_ad(!is_in_unflushed_spaces);
+ ut_ad(!needs_flush());
}
+ else
+ flush_low();
+}
- switch (n_pending--) {
- case 0:
- ut_error;
- case 1:
- if (space->belongs_in_lru())
- /* The node must be put back to the LRU list */
- UT_LIST_ADD_FIRST(fil_system.LRU, this);
+/** @return the size in pages (0 if unreadable) */
+inline uint32_t fil_space_t::get_size()
+{
+ if (!size)
+ {
+ mutex_enter(&fil_system.mutex);
+ read_page0();
+ mutex_exit(&fil_system.mutex);
}
+ return size;
}
#include "fil0crypt.h"
-/** Create a space memory object and put it to the fil_system hash table.
-Error messages are issued to the server log.
-@param[in] name tablespace name
-@param[in] id tablespace identifier
-@param[in] flags tablespace flags
-@param[in] purpose tablespace purpose
-@param[in,out] crypt_data encryption information
-@param[in] mode encryption mode
-@return pointer to created tablespace, to be filled in with fil_space_t::add()
-@retval NULL on failure (such as when the same tablespace exists) */
-fil_space_t*
-fil_space_create(
- const char* name,
- ulint id,
- ulint flags,
- fil_type_t purpose,
- fil_space_crypt_t* crypt_data,
- fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT)
- MY_ATTRIBUTE((warn_unused_result));
-
/*******************************************************************//**
Assigns a new space id for a new single-table tablespace. This works simply by
incrementing the global counter. If 4 billion id's is not enough, we may need
@@ -1427,27 +1505,10 @@ fil_space_free(
@param id tablespace ID
@param size recovered size in pages
@param flags tablespace flags */
-UNIV_INTERN
-void fil_space_set_recv_size_and_flags(ulint id, ulint size, uint32_t flags);
+void fil_space_set_recv_size_and_flags(ulint id, uint32_t size,
+ uint32_t flags);
/*******************************************************************//**
-Returns the size of the space in pages. The tablespace must be cached in the
-memory cache.
-@return space size, 0 if space not found */
-ulint
-fil_space_get_size(
-/*===============*/
- ulint id); /*!< in: space id */
-
-/** Opens all system tablespace data files. They stay open until the
-database server shutdown. This should be called at a server startup after the
-space objects for the system tablespace have been created. The
-purpose of this operation is to make sure we never run out of file descriptors
-if we need to read from the insert buffer. */
-void fil_open_system_tablespace_files();
-/** Close all tablespace files at shutdown */
-void fil_close_all_files();
-/*******************************************************************//**
Sets the max tablespace id counter if the given number is bigger than the
previous value. */
void
@@ -1464,50 +1525,6 @@ fil_write_flushed_lsn(
lsn_t lsn)
MY_ATTRIBUTE((warn_unused_result));
-/** Acquire a tablespace when it could be dropped concurrently.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@param[in] silent whether to silently ignore missing tablespaces
-@return the tablespace
-@retval NULL if missing or being deleted */
-fil_space_t* fil_space_acquire_low(ulint id, bool silent)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Acquire a tablespace when it could be dropped concurrently.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing or being deleted or truncated */
-inline
-fil_space_t*
-fil_space_acquire(ulint id)
-{
- return (fil_space_acquire_low(id, false));
-}
-
-/** Acquire a tablespace that may not exist.
-Used by background threads that do not necessarily hold proper locks
-for concurrency control.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing or being deleted */
-inline
-fil_space_t*
-fil_space_acquire_silent(ulint id)
-{
- return (fil_space_acquire_low(id, true));
-}
-
-/** Acquire a tablespace for reading or writing a block,
-when it could be dropped concurrently.
-@param[in] id tablespace ID
-@return the tablespace
-@retval NULL if missing */
-fil_space_t*
-fil_space_acquire_for_io(ulint id);
-
/** Replay a file rename operation if possible.
@param[in] space_id tablespace identifier
@param[in] name old file name
@@ -1522,17 +1539,6 @@ fil_op_replay_rename(
const char* new_name)
MY_ATTRIBUTE((warn_unused_result));
-/** Determine whether a table can be accessed in operations that are
-not (necessarily) protected by meta-data locks.
-(Rollback would generally be protected, but rollback of
-FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks
-but only by InnoDB table locks, which may be broken by
-lock_remove_all_on_table().)
-@param[in] table persistent table
-checked @return whether the table is accessible */
-bool fil_table_accessible(const dict_table_t* table)
- MY_ATTRIBUTE((warn_unused_result, nonnull));
-
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
@param[in] if_exists whether to ignore missing tablespace
@@ -1585,7 +1591,7 @@ fil_ibd_create(
const char* name,
const char* path,
ulint flags,
- ulint size,
+ uint32_t size,
fil_encryption_t mode,
uint32_t key_id,
dberr_t* err)
@@ -1683,7 +1689,7 @@ fil_file_readdir_next_file(
memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
-@param[in] name Tablespace name used in fil_space_create().
+@param[in] name Tablespace name used in fil_space_t::create().
@param[in] table_flags table flags
@return the tablespace
@retval NULL if no matching tablespace exists in the memory cache */
@@ -1697,74 +1703,7 @@ fil_space_for_table_exists_in_mem(
@param[in,out] space tablespace
@param[in] size desired size in pages
@return whether the tablespace is at least as big as requested */
-bool
-fil_space_extend(
- fil_space_t* space,
- ulint size);
-
-struct fil_io_t
-{
- /** error code */
- dberr_t err;
- /** file; node->space->release_for_io() must follow fil_io(sync=true) call */
- fil_node_t *node;
-};
-
-/** Reads or writes data. This operation could be asynchronous (aio).
-
-@param[in] type IO context
-@param[in] sync true if synchronous aio is desired
-@param[in] page_id page id
-@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
-@param[in] byte_offset remainder of offset in bytes; in aio this
- must be divisible by the OS block size
-@param[in] len how many bytes to read or write; this must
- not cross a file boundary; in aio this must
- be a block size multiple
-@param[in,out] buf buffer where to store read data or from where
- to write; in aio this must be appropriately
- aligned
-@param[in] message message for aio handler if non-sync aio
- used, else ignored
-@param[in] ignore whether to ignore errors
-@param[in] punch_hole punch the hole to the file for page_compressed
- tablespace
-@return status and file descriptor */
-fil_io_t
-fil_io(
- const IORequest& type,
- bool sync,
- const page_id_t page_id,
- ulint zip_size,
- ulint byte_offset,
- ulint len,
- void* buf,
- void* message,
- bool ignore = false,
- bool punch_hole = false);
-
-/**********************************************************************//**
-Waits for an aio operation to complete. This function is used to write the
-handler for completed requests. The aio array of pending requests is divided
-into segments (see os0file.cc for more info). The thread specifies which
-segment it wants to wait for. */
-void
-fil_aio_wait(
-/*=========*/
- ulint segment); /*!< in: the number of the segment in the aio
- array to wait for */
-/**********************************************************************//**
-Flushes to disk possible writes cached by the OS. If the space does not exist
-or is being dropped, does not do anything. */
-void
-fil_flush(
-/*======*/
- ulint space_id); /*!< in: file space id (this can be a group of
- log files or a tablespace of the database) */
-/** Flush a tablespace.
-@param[in,out] space tablespace to flush */
-void
-fil_flush(fil_space_t* space);
+bool fil_space_extend(fil_space_t *space, uint32_t size);
/** Flush to disk the writes in file spaces of the given type
possibly cached by the OS. */
@@ -1841,7 +1780,7 @@ for the first time since the latest fil_names_clear().
@return whether any FILE_MODIFY record was written */
inline bool fil_names_write_if_was_clean(fil_space_t* space)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
if (space == NULL) {
return(false);
@@ -1858,23 +1797,6 @@ inline bool fil_names_write_if_was_clean(fil_space_t* space)
return(was_clean);
}
-/** During crash recovery, open a tablespace if it had not been opened
-yet, to get valid size and flags.
-@param[in,out] space tablespace */
-inline void fil_space_open_if_needed(fil_space_t* space)
-{
- ut_ad(recv_recovery_is_on());
-
- if (space->size == 0) {
- /* Initially, size and flags will be set to 0,
- until the files are opened for the first time.
- fil_space_get_size() will open the file
- and adjust the size and flags. */
- ut_d(ulint size =) fil_space_get_size(space->id);
- ut_ad(size == space->size);
- }
-}
-
/** On a log checkpoint, reset fil_names_dirty_and_write() flags
and write out FILE_MODIFY and FILE_CHECKPOINT if needed.
@param[in] lsn checkpoint LSN
diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h
index 759970bb46d..7db85e87ed0 100644
--- a/storage/innobase/include/fsp0file.h
+++ b/storage/innobase/include/fsp0file.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
-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
@@ -68,7 +68,7 @@ public:
/* No op */
}
- Datafile(const char* name, ulint flags, ulint size, ulint order)
+ Datafile(const char* name, ulint flags, uint32_t size, ulint order)
:
m_name(mem_strdup(name)),
m_filepath(),
@@ -268,6 +268,14 @@ public:
return(m_handle);
}
+ /** @return detached file handle */
+ pfs_os_file_t detach()
+ {
+ pfs_os_file_t detached = m_handle;
+ m_handle = OS_FILE_CLOSED;
+ return detached;
+ }
+
/** Get Datafile::m_order.
@return m_order */
ulint order() const
@@ -431,7 +439,7 @@ private:
/** size in megabytes or pages; converted from megabytes to
pages in SysTablespace::normalize_size() */
- ulint m_size;
+ uint32_t m_size;
/** ordinal position of this datafile in the tablespace */
ulint m_order;
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 31c66cb57ea..7245db39273 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -316,11 +316,9 @@ inline uint32_t fsp_header_get_field(const page_t* page, ulint field)
/** Read the flags from the tablespace header page.
@param[in] page first page of a tablespace
@return the contents of FSP_SPACE_FLAGS */
-inline
-ulint
-fsp_header_get_flags(const page_t* page)
+inline uint32_t fsp_header_get_flags(const page_t *page)
{
- return(fsp_header_get_field(page, FSP_SPACE_FLAGS));
+ return fsp_header_get_field(page, FSP_SPACE_FLAGS);
}
/** Get the byte offset of encryption information in page 0.
@@ -359,7 +357,7 @@ fsp_header_init_fields(
@param[in,out] space tablespace
@param[in] size current size in blocks
@param[in,out] mtr mini-transaction */
-void fsp_header_init(fil_space_t* space, ulint size, mtr_t* mtr)
+void fsp_header_init(fil_space_t* space, uint32_t size, mtr_t* mtr)
MY_ATTRIBUTE((nonnull));
/** Create a new segment.
@@ -411,7 +409,7 @@ buf_block_t*
fseg_alloc_free_page_general(
/*=========================*/
fseg_header_t* seg_header,/*!< in/out: segment header */
- ulint hint, /*!< in: hint of which page would be
+ uint32_t hint, /*!< in: hint of which page would be
desirable */
byte direction,/*!< in: if the new page is needed because
of an index page split, and records are
@@ -468,12 +466,12 @@ free pages available.
@return true if we were able to make the reservation */
bool
fsp_reserve_free_extents(
- ulint* n_reserved,
+ uint32_t* n_reserved,
fil_space_t* space,
- ulint n_ext,
+ uint32_t n_ext,
fsp_reserve_t alloc_type,
mtr_t* mtr,
- ulint n_pages = 2);
+ uint32_t n_pages = 2);
/** Free a page in a file segment.
@param[in,out] seg_header file segment header
@@ -484,7 +482,7 @@ void
fseg_free_page(
fseg_header_t* seg_header,
fil_space_t* space,
- ulint offset,
+ uint32_t offset,
mtr_t* mtr);
/** Determine whether a page is free.
@param[in,out] space tablespace
@@ -736,7 +734,7 @@ inline ulint xdes_calc_descriptor_index(ulint zip_size, ulint offset)
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] offset page offset
@return descriptor page offset */
-inline ulint xdes_calc_descriptor_page(ulint zip_size, ulint offset)
+inline uint32_t xdes_calc_descriptor_page(ulint zip_size, uint32_t offset)
{
compile_time_assert(UNIV_PAGE_SIZE_MAX > XDES_ARR_OFFSET
+ (UNIV_PAGE_SIZE_MAX / FSP_EXTENT_SIZE_MAX)
@@ -754,8 +752,8 @@ inline ulint xdes_calc_descriptor_page(ulint zip_size, ulint offset)
ut_ad(!zip_size
|| zip_size > XDES_ARR_OFFSET
+ (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE);
- return ut_2pow_round<ulint>(offset,
- zip_size ? zip_size : srv_page_size);
+ return ut_2pow_round(offset,
+ uint32_t(zip_size ? zip_size : srv_page_size));
}
#endif /* UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/fsp0space.h b/storage/innobase/include/fsp0space.h
index 632c65e14cc..c00c8d689bf 100644
--- a/storage/innobase/include/fsp0space.h
+++ b/storage/innobase/include/fsp0space.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, 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
@@ -163,9 +163,9 @@ public:
void shutdown();
/** @return the sum of the file sizes of each Datafile */
- ulint get_sum_of_sizes() const
+ uint32_t get_sum_of_sizes() const
{
- ulint sum = 0;
+ uint32_t sum = 0;
for (const_iterator it = begin(); it != end(); ++it) {
sum += it->m_size;
diff --git a/storage/innobase/include/fsp0sysspace.h b/storage/innobase/include/fsp0sysspace.h
index bcb8dd5e5e9..2e0a395f71c 100644
--- a/storage/innobase/include/fsp0sysspace.h
+++ b/storage/innobase/include/fsp0sysspace.h
@@ -30,7 +30,7 @@ Created 2013-7-26 by Kevin Lewis
/** If the last data file is auto-extended, we add this many pages to it
at a time. We have to make this public because it is a config variable. */
-extern ulong sys_tablespace_auto_extend_increment;
+extern uint sys_tablespace_auto_extend_increment;
/** Data structure that contains the information about shared tablespaces.
Currently this can be the system tablespace or a temporary table tablespace */
@@ -120,7 +120,7 @@ public:
/** Set the last file size.
@param[in] size the size to set */
- void set_last_file_size(ulint size)
+ void set_last_file_size(uint32_t size)
{
ut_ad(!m_files.empty());
m_files.back().m_size = size;
@@ -128,7 +128,7 @@ public:
/** Get the size of the last data file in the tablespace
@return the size of the last data file in the array */
- ulint last_file_size() const
+ uint32_t last_file_size() const
{
ut_ad(!m_files.empty());
return(m_files.back().m_size);
@@ -136,7 +136,7 @@ public:
/**
@return the autoextend increment in pages. */
- ulint get_autoextend_increment() const
+ uint32_t get_autoextend_increment() const
{
return sys_tablespace_auto_extend_increment
<< (20 - srv_page_size_shift);
@@ -144,7 +144,7 @@ public:
/**
@return next increment size */
- ulint get_increment() const;
+ uint32_t get_increment() const;
/** Open or create the data files
@param[in] is_temp whether this is a temporary tablespace
@@ -240,8 +240,7 @@ private:
/** if true, then we auto-extend the last data file */
bool m_auto_extend_last_file;
- /** if != 0, this tells the max size auto-extending may increase the
- last data file size */
+ /** maximum size of the last data file (0=unlimited) */
ulint m_last_file_size_max;
/** If the following is true we do not allow
diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
index 5057ed98aba..f8e4c06baae 100644
--- a/storage/innobase/include/fsp0types.h
+++ b/storage/innobase/include/fsp0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 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
@@ -24,9 +24,7 @@ File space management types
Created May 26, 2009 Vasil Dimov
*******************************************************/
-#ifndef fsp0types_h
-#define fsp0types_h
-
+#pragma once
#include <cstddef>
/** The fil_space_t::id of the redo log. All persistent tablespaces
@@ -402,4 +400,6 @@ in full crc32 format. */
/* @} */
-#endif /* fsp0types_h */
+struct fil_node_t;
+struct fil_space_t;
+class buf_page_t;
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index 3dca92235c7..15bf30bc5d5 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
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 5c35e5dac4f..5e0381ccd56 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -316,19 +316,11 @@ public:
/** fts_t destructor. */
~fts_t();
- /** Mutex protecting bg_threads* and fts_add_wq. */
- ib_mutex_t bg_threads_mutex;
-
- /** Whether the ADDED table record sync-ed after
- crash recovery; protected by bg_threads_mutex */
+ /** Whether the ADDED table record sync-ed after crash recovery */
unsigned added_synced:1;
- /** Whether the table holds dict_sys.mutex;
- protected by bg_threads_mutex */
+ /** Whether the table holds dict_sys.mutex */
unsigned dict_locked:1;
- /** Number of background threads accessing this table. */
- ulint bg_threads;
-
/** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL
if the thread has not yet been created. Each work item is a
fts_trx_doc_ids_t*. */
diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h
index 44c3ab77695..f5760a16c0e 100644
--- a/storage/innobase/include/fts0types.h
+++ b/storage/innobase/include/fts0types.h
@@ -131,8 +131,6 @@ struct fts_cache_t {
intialization, it has different
SYNC level as above cache lock */
- ib_mutex_t optimize_lock; /*!< Lock for OPTIMIZE */
-
ib_mutex_t deleted_lock; /*!< Lock covering deleted_doc_ids */
ib_mutex_t doc_id_lock; /*!< Lock covering Doc ID */
diff --git a/storage/innobase/include/gis0rtree.h b/storage/innobase/include/gis0rtree.h
index f064df01679..f7a2d6cd4cd 100644
--- a/storage/innobase/include/gis0rtree.h
+++ b/storage/innobase/include/gis0rtree.h
@@ -169,10 +169,10 @@ void
rtr_non_leaf_stack_push(
/*====================*/
rtr_node_path_t* path, /*!< in/out: search path */
- ulint pageno, /*!< in: pageno to insert */
+ uint32_t pageno, /*!< in: pageno to insert */
node_seq_t seq_no, /*!< in: Node sequence num */
ulint level, /*!< in: index level */
- ulint child_no, /*!< in: child page no */
+ uint32_t child_no, /*!< in: child page no */
btr_pcur_t* cursor, /*!< in: position cursor */
double mbr_inc); /*!< in: MBR needs to be
enlarged */
diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic
index 2076b24b9b1..82747bdc95a 100644
--- a/storage/innobase/include/gis0rtree.ic
+++ b/storage/innobase/include/gis0rtree.ic
@@ -96,10 +96,10 @@ void
rtr_non_leaf_stack_push(
/*====================*/
rtr_node_path_t* path, /*!< in/out: search path */
- ulint pageno, /*!< in: pageno to insert */
+ uint32_t pageno, /*!< in: pageno to insert */
node_seq_t seq_no, /*!< in: Node sequence num */
ulint level, /*!< in: index page level */
- ulint child_no, /*!< in: child page no */
+ uint32_t child_no, /*!< in: child page no */
btr_pcur_t* cursor, /*!< in: position cursor */
double mbr_inc) /*!< in: MBR needs to be
enlarged */
diff --git a/storage/innobase/include/gis0type.h b/storage/innobase/include/gis0type.h
index a1e0a878cb2..55944bfcce3 100644
--- a/storage/innobase/include/gis0type.h
+++ b/storage/innobase/include/gis0type.h
@@ -37,15 +37,15 @@ Created 2013/03/27 Jimmy Yang
#include <vector>
#include <forward_list>
-/* Node Sequence Number. Only updated when page splits */
-typedef ib_uint32_t node_seq_t;
+/** Node Sequence Number. Only updated when page splits */
+typedef uint32_t node_seq_t;
/* RTree internal non-leaf Nodes to be searched, from root to leaf */
-typedef struct node_visit {
- ulint page_no; /*!< the page number */
+struct node_visit_t {
+ uint32_t page_no; /*!< the page number */
node_seq_t seq_no; /*!< the SSN (split sequence number */
ulint level; /*!< the page's index level */
- ulint child_no; /*!< child page num if for parent
+ uint32_t child_no; /*!< child page num if for parent
recording */
btr_pcur_t* cursor; /*!< cursor structure if we positioned
FIXME: there is no need to use whole
@@ -53,7 +53,7 @@ typedef struct node_visit {
members */
double mbr_inc; /*!< whether this node needs to be
enlarged for insertion */
-} node_visit_t;
+};
typedef std::vector<node_visit_t, ut_allocator<node_visit_t> > rtr_node_path_t;
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 220e697d556..a9295ced6db 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -659,11 +659,6 @@ lock_trx_lock_list_init(
/*====================*/
trx_lock_list_t* lock_list); /*!< List to initialise */
-/*******************************************************************//**
-Set the lock system timeout event. */
-void
-lock_set_timeout_event();
-/*====================*/
/*********************************************************************//**
Checks that a transaction id is sensible, i.e., not in the future.
@return true if ok */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 9eae5369d48..5a26b4baf7d 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -35,7 +35,6 @@ Created 12/9/1995 Heikki Tuuri
#define log0log_h
#include "log0types.h"
-#include "ut0mutex.h"
#include "os0file.h"
#include "span.h"
#include <atomic>
@@ -88,50 +87,12 @@ log_free_check(void);
@param[in] len requested minimum size in bytes */
void log_buffer_extend(ulong len);
-/** Check margin not to overwrite transaction log from the last checkpoint.
-If would estimate the log write to exceed the log_capacity,
-waits for the checkpoint is done enough.
-@param[in] len length of the data to be written */
-
-void
-log_margin_checkpoint_age(
- ulint len);
-
-/** Open the log for log_write_low. The log must be closed with log_close.
-@param[in] len length of the data to be written
-@return start lsn of the log record */
-lsn_t
-log_reserve_and_open(
- ulint len);
-/************************************************************//**
-Writes to the log the string given. It is assumed that the caller holds the
-log mutex. */
-void
-log_write_low(
-/*==========*/
- const byte* str, /*!< in: string */
- ulint str_len); /*!< in: string length */
-/************************************************************//**
-Closes the log.
-@return lsn */
-lsn_t
-log_close(void);
-/*===========*/
/** Read the current LSN. */
#define log_get_lsn() log_sys.get_lsn()
/** Read the durable LSN */
#define log_get_flush_lsn() log_sys.get_flushed_lsn()
-/****************************************************************
-Get log_sys::max_modified_age_async. It is OK to read the value without
-holding log_sys::mutex because it is constant.
-@return max_modified_age_async */
-UNIV_INLINE
-lsn_t
-log_get_max_modified_age_async(void);
-/*================================*/
-
/** Calculate the recommended highest values for lsn - last_checkpoint_lsn
and lsn - buf_pool.get_oldest_modification().
@param[in] file_size requested innodb_log_file_size
@@ -159,30 +120,22 @@ void
log_buffer_flush_to_disk(
bool sync = true);
-/** Make a checkpoint. Note that this function does not flush dirty
-blocks from the buffer pool: it only checks what is lsn of the oldest
-modification in the pool, and writes information about the lsn in
-log file. Use log_make_checkpoint() to flush also the pool.
-@return true if success, false if a checkpoint write was already running */
-bool log_checkpoint();
-
/** Make a checkpoint */
-void log_make_checkpoint();
+ATTRIBUTE_COLD void log_make_checkpoint();
/** Make a checkpoint at the latest lsn on shutdown. */
-void logs_empty_and_mark_files_at_shutdown();
+ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown();
-/** Write checkpoint info to the log header and invoke log_mutex_exit().
+/** Write checkpoint info to the log header and release log_sys.mutex.
@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */
-void log_write_checkpoint_info(lsn_t end_lsn);
+ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn);
/**
Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
objects! */
-void
-log_check_margins(void);
+ATTRIBUTE_COLD void log_check_margins();
/************************************************************//**
Gets a log block flush bit.
@@ -395,9 +348,6 @@ or the MySQL version that created the redo log file. */
header */
#define LOG_FILE_HDR_SIZE (4 * OS_FILE_LOG_BLOCK_SIZE)
-typedef ib_mutex_t LogSysMutex;
-typedef ib_mutex_t FlushOrderMutex;
-
/** Memory mapped file */
class mapped_file_t
{
@@ -517,37 +467,32 @@ struct log_t{
private:
/** The log sequence number of the last change of durable InnoDB files */
- MY_ALIGNED(CACHE_LINE_SIZE)
+ MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE)
std::atomic<lsn_t> lsn;
/** the first guaranteed-durable log sequence number */
std::atomic<lsn_t> flushed_to_disk_lsn;
-public:
- /** first free offset within the log buffer in use */
- size_t buf_free;
-private:
/** set when there may be need to flush the log buffer, or
preflush buffer pool pages, or initiate a log checkpoint.
This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */
std::atomic<bool> check_flush_or_checkpoint_;
public:
-
/** mutex protecting the log */
- MY_ALIGNED(CACHE_LINE_SIZE)
- LogSysMutex mutex;
+ MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t mutex;
+ /** first free offset within the log buffer in use */
+ size_t buf_free;
+ /** recommended maximum size of buf, after which the buffer is flushed */
+ size_t max_buf_free;
/** mutex to serialize access to the flush list when we are putting
dirty blocks in the list. The idea behind this mutex is to be able
to release log_sys.mutex during mtr_commit and still ensure that
insertions in the flush_list happen in the LSN order. */
- MY_ALIGNED(CACHE_LINE_SIZE) FlushOrderMutex
- log_flush_order_mutex;
+ MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t flush_order_mutex;
/** log_buffer, append data here */
byte *buf;
/** log_buffer, writing data to file from this buffer.
Before flushing write_buf is swapped with flush_buf */
byte *flush_buf;
- /** recommended maximum size of buf, after which the buffer is flushed */
- size_t max_buf_free;
- /** Log file stuff. Protected by mutex or write_mutex. */
+ /** Log file stuff. Protected by mutex. */
struct file {
/** format of the redo log: e.g., FORMAT_10_5 */
uint32_t format;
@@ -664,17 +609,6 @@ public:
buf_pool.get_oldest_modification()
is exceeded, we start an
asynchronous preflush of pool pages */
- lsn_t max_modified_age_sync;
- /*!< when this recommended
- value for lsn -
- buf_pool.get_oldest_modification()
- is exceeded, we start a
- synchronous preflush of pool pages */
- lsn_t max_checkpoint_age_async;
- /*!< when this checkpoint age
- is exceeded we start an
- asynchronous writing of a new
- checkpoint */
lsn_t max_checkpoint_age;
/*!< this is the maximum allowed value
for lsn - last_checkpoint_lsn when a
@@ -721,7 +655,10 @@ public:
{ flushed_to_disk_lsn.store(lsn, std::memory_order_relaxed); }
bool check_flush_or_checkpoint() const
- { return check_flush_or_checkpoint_.load(std::memory_order_relaxed); }
+ {
+ return UNIV_UNLIKELY
+ (check_flush_or_checkpoint_.load(std::memory_order_relaxed));
+ }
void set_check_flush_or_checkpoint(bool flag= true)
{ check_flush_or_checkpoint_.store(flag, std::memory_order_relaxed); }
@@ -784,11 +721,6 @@ extern log_t log_sys;
extern bool log_write_lock_own();
#endif
-/** Gets the log capacity. It is OK to read the value without
-holding log_sys.mutex because it is constant.
-@return log capacity */
-inline lsn_t log_get_capacity(void) { return log_sys.log_capacity; }
-
/** Calculate the offset of a log sequence number.
@param[in] lsn log sequence number
@return offset within the log */
@@ -797,7 +729,9 @@ inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const
ut_ad(this == &log_sys.log);
/* The lsn parameters are updated while holding both the mutexes
and it is ok to have either of them while reading */
- ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
+#ifdef SAFE_MUTEX
+ ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
+#endif /* SAFE_MUTEX */
const lsn_t size = capacity();
lsn_t l= lsn - this->lsn;
if (longlong(l) < 0) {
@@ -810,41 +744,23 @@ inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const
return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE));
}
-inline void log_t::file::set_lsn(lsn_t a_lsn) {
- ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
- lsn = a_lsn;
+inline void log_t::file::set_lsn(lsn_t a_lsn)
+{
+#ifdef SAFE_MUTEX
+ ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
+#endif /* SAFE_MUTEX */
+ lsn= a_lsn;
}
-inline void log_t::file::set_lsn_offset(lsn_t a_lsn) {
- ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
- ut_ad((lsn % OS_FILE_LOG_BLOCK_SIZE) == (a_lsn % OS_FILE_LOG_BLOCK_SIZE));
- lsn_offset = a_lsn;
+inline void log_t::file::set_lsn_offset(lsn_t a_lsn)
+{
+#ifdef SAFE_MUTEX
+ ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
+#endif /* SAFE_MUTEX */
+ ut_ad((lsn % OS_FILE_LOG_BLOCK_SIZE) == (a_lsn % OS_FILE_LOG_BLOCK_SIZE));
+ lsn_offset= a_lsn;
}
-/** Test if flush order mutex is owned. */
-#define log_flush_order_mutex_own() \
- mutex_own(&log_sys.log_flush_order_mutex)
-
-/** Acquire the flush order mutex. */
-#define log_flush_order_mutex_enter() do { \
- mutex_enter(&log_sys.log_flush_order_mutex); \
-} while (0)
-/** Release the flush order mutex. */
-# define log_flush_order_mutex_exit() do { \
- mutex_exit(&log_sys.log_flush_order_mutex); \
-} while (0)
-
-/** Test if log sys mutex is owned. */
-#define log_mutex_own() mutex_own(&log_sys.mutex)
-
-
-/** Acquire the log sys mutex. */
-#define log_mutex_enter() mutex_enter(&log_sys.mutex)
-
-
-/** Release the log sys mutex. */
-#define log_mutex_exit() mutex_exit(&log_sys.mutex)
-
#include "log0log.ic"
#endif
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 4fdc2b0258e..d503e3ffec9 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -255,7 +255,7 @@ log_reserve_and_write_fast(
ulint len,
lsn_t* start_lsn)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(len > 0);
const ulint data_len = len
@@ -290,18 +290,6 @@ log_reserve_and_write_fast(
return lsn;
}
-/****************************************************************
-Get log_sys::max_modified_age_async. It is OK to read the value without
-holding log_sys::mutex because it is constant.
-@return max_modified_age_async */
-UNIV_INLINE
-lsn_t
-log_get_max_modified_age_async(void)
-/*================================*/
-{
- return(log_sys.max_modified_age_async);
-}
-
/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index b8d7e40246c..f822a874565 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -33,9 +33,6 @@ Created 9/20/1997 Heikki Tuuri
#include <deque>
-/** Is recv_writer_thread active? */
-extern bool recv_writer_thread_active;
-
/** @return whether recovery is currently running. */
#define recv_recovery_is_on() UNIV_UNLIKELY(recv_sys.recovery_on)
@@ -53,21 +50,12 @@ ATTRIBUTE_COLD void recv_recover_page(fil_space_t* space, buf_page_t* bpage)
MY_ATTRIBUTE((nonnull));
/** Start recovering from a redo log checkpoint.
-@see recv_recovery_from_checkpoint_finish
@param[in] flush_lsn FIL_PAGE_FILE_FLUSH_LSN
of first system tablespace page
@return error code or DB_SUCCESS */
dberr_t
recv_recovery_from_checkpoint_start(
lsn_t flush_lsn);
-/** Complete recovery from a checkpoint. */
-void
-recv_recovery_from_checkpoint_finish(void);
-/********************************************************//**
-Initiates the rollback of active transactions. */
-void
-recv_recovery_rollback_active(void);
-/*===============================*/
/** Whether to store redo log records in recv_sys.pages */
enum store_t {
@@ -226,16 +214,6 @@ struct recv_sys_t
/** whether recv_recover_page(), invoked from buf_page_read_complete(),
should apply log records*/
bool apply_log_recs;
-
- ib_mutex_t writer_mutex;/*!< mutex coordinating
- flushing between recv_writer_thread and
- the recovery thread. */
- os_event_t flush_start;/*!< event to activate
- page cleaner threads */
- os_event_t flush_end;/*!< event to signal that the page
- cleaner has finished the request */
- /** whether to flush from buf_pool.LRU instead of buf_pool.flush_list */
- bool flush_lru;
/** whether recv_apply_hashed_log_recs() is running */
bool apply_batch_on;
byte* buf; /*!< buffer for parsing log records */
@@ -309,9 +287,10 @@ private:
@param page_id page identifier
@param p iterator pointing to page_id
@param mtr mini-transaction
+ @param b pre-allocated buffer pool block
@return whether the page was successfully initialized */
inline buf_block_t *recover_low(const page_id_t page_id, map::iterator &p,
- mtr_t &mtr);
+ mtr_t &mtr, buf_block_t *b);
/** Attempt to initialize a page based on redo log records.
@param page_id page identifier
@return the recovered block
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 4487bf94e01..cf8f37c3fa5 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -106,7 +106,7 @@ struct mtr_t {
/** Commit a mini-transaction that did not modify any pages,
but generated some redo log on a higher level, such as
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
- The caller must invoke log_mutex_enter() and log_mutex_exit().
+ The caller must hold log_sys.mutex.
This is to be used at log_checkpoint().
@param checkpoint_lsn the log sequence number of a checkpoint, or 0 */
void commit_files(lsn_t checkpoint_lsn= 0);
@@ -628,8 +628,8 @@ private:
/** Append the redo log records to the redo log buffer.
@param len number of bytes to write
- @return start_lsn */
- inline lsn_t finish_write(ulint len);
+ @return {start_lsn,flush_ahead} */
+ inline std::pair<lsn_t,bool> finish_write(ulint len);
/** Release the resources */
inline void release_resources();
diff --git a/storage/innobase/include/os0api.h b/storage/innobase/include/os0api.h
deleted file mode 100644
index bd9dc5b73a1..00000000000
--- a/storage/innobase/include/os0api.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***********************************************************************
-
-Copyright (c) 2017, 2019, 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
-
-***********************************************************************/
-
-/**************************************************//**
-@file os0api.h
-The interface to the helper functions.
-These functions are used on os0file.h where
-including full full header is not feasible and
-implemented on buf0buf.cc and fil0fil.cc.
-*******************************************************/
-
-#ifndef OS_API_H
-#define OS_API_H 1
-
-/** Page control block */
-class buf_page_t;
-
-/** File Node */
-struct fil_node_t;
-
-/**
-Calculate the length of trim (punch_hole) operation.
-@param[in] bpage Page control block
-@param[in] write_length Write length
-@return length of the trim or zero. */
-ulint
-buf_page_get_trim_length(
- const buf_page_t* bpage,
- ulint write_length)
- MY_ATTRIBUTE((warn_unused_result));
-
-#endif /* OS_API_H */
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 08ea482333b..5e0039304b0 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -37,7 +37,6 @@ Created 10/21/1995 Heikki Tuuri
#define os0file_h
#include "fsp0types.h"
-#include "os0api.h"
#include "tpool.h"
#ifndef _WIN32
@@ -46,10 +45,6 @@ Created 10/21/1995 Heikki Tuuri
#include <time.h>
#endif /* !_WIN32 */
-/** File node of a tablespace or the log data space */
-struct fil_node_t;
-struct fil_space_t;
-
extern bool os_has_said_disk_full;
/** File offset in bytes */
@@ -160,6 +155,7 @@ static const ulint OS_FILE_NORMAL = 62;
static const ulint OS_DATA_FILE = 100;
static const ulint OS_LOG_FILE = 101;
static const ulint OS_DATA_TEMP_FILE = 102;
+static const ulint OS_DATA_FILE_NO_O_DIRECT = 103;
/* @} */
/** Error codes from os_file_get_last_error @{ */
@@ -182,182 +178,82 @@ static const ulint OS_FILE_OPERATION_NOT_SUPPORTED = 125;
static const ulint OS_FILE_ERROR_MAX = 200;
/* @} */
-/** Types for AIO operations @{ */
-
-/** No transformations during read/write, write as is. */
-#define IORequestRead IORequest(IORequest::READ)
-#define IORequestWrite IORequest(IORequest::WRITE)
-
/**
The I/O context that is passed down to the low level IO code */
class IORequest
{
public:
- /** Buffer pool flush types */
- enum flush_t
+ enum Type
{
- /** via buf_pool.LRU */
- LRU= 0,
- /** via buf_pool.flush_list */
- FLUSH_LIST,
- /** single page of buf_poof.LRU */
- SINGLE_PAGE
+ /** Synchronous read */
+ READ_SYNC= 2,
+ /** Asynchronous read; some errors will be ignored */
+ READ_ASYNC= READ_SYNC | 1,
+ /** Possibly partial read; only used with
+ os_file_read_no_error_handling() */
+ READ_MAYBE_PARTIAL= READ_SYNC | 4,
+ /** Read for doublewrite buffer recovery */
+ DBLWR_RECOVER= READ_SYNC | 8,
+ /** Synchronous write */
+ WRITE_SYNC= 16,
+ /** Asynchronous write */
+ WRITE_ASYNC= WRITE_SYNC | 1,
+ /** A doublewrite batch */
+ DBLWR_BATCH= WRITE_ASYNC | 8,
+ /** Write data; evict the block on write completion */
+ WRITE_LRU= WRITE_ASYNC | 32,
+ /** Write data and punch hole for the rest */
+ PUNCH= WRITE_ASYNC | 64,
+ /** Write data and punch hole; evict the block on write completion */
+ PUNCH_LRU= PUNCH | WRITE_LRU,
+ /** Zero out a range of bytes in fil_space_t::io() */
+ PUNCH_RANGE= WRITE_SYNC | 128,
};
- IORequest(ulint type= READ, buf_page_t *bpage= nullptr,
- flush_t flush_type= LRU) :
- m_bpage(bpage), m_type(static_cast<uint16_t>(type)),
- m_flush_type(flush_type) {}
-
- /** Flags passed in the request, they can be ORred together. */
- enum {
- READ = 1,
- WRITE = 2,
-
- /** Double write buffer recovery. */
- DBLWR_RECOVER = 4,
-
- /** Enumarations below can be ORed to READ/WRITE above*/
-
- /** Data file */
- DATA_FILE = 8,
-
- /** Disable partial read warnings */
- DISABLE_PARTIAL_IO_WARNINGS = 32,
-
- /** Use punch hole if available*/
- PUNCH_HOLE = 64,
- };
-
- /** @return true if it is a read request */
- bool is_read() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return((m_type & READ) == READ);
- }
-
- /** @return true if it is a write request */
- bool is_write() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return((m_type & WRITE) == WRITE);
- }
-
- /** Clear the punch hole flag */
- void clear_punch_hole()
- {
- m_type &= uint16_t(~PUNCH_HOLE);
- }
+ constexpr IORequest(buf_page_t *bpage, fil_node_t *node, Type type) :
+ bpage(bpage), node(node), type(type) {}
- /** @return true if partial read warning disabled */
- bool is_partial_io_warning_disabled() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return !!(m_type & DISABLE_PARTIAL_IO_WARNINGS);
- }
+ constexpr IORequest(Type type= READ_SYNC, buf_page_t *bpage= nullptr) :
+ bpage(bpage), type(type) {}
- /** Disable partial read warnings */
- void disable_partial_io_warnings()
- {
- m_type |= DISABLE_PARTIAL_IO_WARNINGS;
- }
+ bool is_read() const { return (type & READ_SYNC) != 0; }
+ bool is_write() const { return (type & WRITE_SYNC) != 0; }
+ bool is_LRU() const { return (type & (WRITE_LRU ^ WRITE_ASYNC)) != 0; }
+ bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; }
- /** @return true if punch hole should be used */
- bool punch_hole() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return((m_type & PUNCH_HOLE) == PUNCH_HOLE);
- }
-
- /** @return true if the read should be validated */
- bool validate() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return(is_read() ^ is_write());
- }
-
- /** Set the punch hole flag */
- void set_punch_hole()
- {
- if (is_punch_hole_supported()) {
- m_type |= PUNCH_HOLE;
- }
- }
-
- /** Set the pointer to file node for IO
- @param[in] node File node */
- inline void set_fil_node(fil_node_t* node);
-
- bool operator==(const IORequest& rhs) const
- {
- return(m_type == rhs.m_type);
- }
-
- /** Note that the IO is for double write recovery. */
- void dblwr_recover()
- {
- m_type |= DBLWR_RECOVER;
- }
-
- /** @return true if the request is from the dblwr recovery */
- bool is_dblwr_recover() const
- MY_ATTRIBUTE((warn_unused_result))
- {
- return((m_type & DBLWR_RECOVER) == DBLWR_RECOVER);
- }
-
- /** @return true if punch hole is supported */
- static bool is_punch_hole_supported()
- {
-
- /* In this debugging mode, we act as if punch hole is supported,
- and then skip any calls to actually punch a hole here.
- In this way, Transparent Page Compression is still being tested. */
- DBUG_EXECUTE_IF("ignore_punch_hole",
- return(true);
- );
-
-#if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
- return(true);
-#else
- return(false);
-#endif /* HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || _WIN32 */
- }
-
- ulint get_trim_length(ulint write_length) const
- {
- return (m_bpage ?
- buf_page_get_trim_length(m_bpage, write_length)
- : 0);
- }
-
- inline bool should_punch_hole() const;
-
- /** Free storage space associated with a section of the file.
- @param[in] fh Open file handle
- @param[in] off Starting offset (SEEK_SET)
- @param[in] len Size of the hole
- @return DB_SUCCESS or error code */
- dberr_t punch_hole(os_file_t fh, os_offset_t off, ulint len);
-
- /** @return the flush type */
- flush_t flush_type() const { return m_flush_type; }
+ /** If requested, free storage space associated with a section of the file.
+ @param off byte offset from the start (SEEK_SET)
+ @param len size of the hole in bytes
+ @return DB_SUCCESS or error code */
+ dberr_t maybe_punch_hole(os_offset_t off, ulint len)
+ {
+ return off && len && node && (type & (PUNCH ^ WRITE_ASYNC))
+ ? punch_hole(off, len)
+ : DB_SUCCESS;
+ }
private:
- /** Page to be written on write operation. */
- buf_page_t* const m_bpage= nullptr;
+ /** Free storage space associated with a section of the file.
+ @param off byte offset from the start (SEEK_SET)
+ @param len size of the hole in bytes
+ @return DB_SUCCESS or error code */
+ dberr_t punch_hole(os_offset_t off, ulint len) const
+ MY_ATTRIBUTE((nonnull));
- /** File node */
- fil_node_t* m_fil_node= nullptr;
+public:
+ /** Page to be written on write operation */
+ buf_page_t* const bpage= nullptr;
- /** Request type bit flags */
- uint16_t m_type= READ;
+ /** File descriptor */
+ fil_node_t *const node= nullptr;
- /** for writes, type of page flush */
- flush_t m_flush_type= LRU;
+ /** Request type bit flags */
+ const Type type;
};
-/* @} */
+constexpr IORequest IORequestRead(IORequest::READ_SYNC);
+constexpr IORequest IORequestReadPartial(IORequest::READ_MAYBE_PARTIAL);
+constexpr IORequest IORequestWrite(IORequest::WRITE_SYNC);
/** Sparse file size information. */
struct os_file_size_t {
@@ -372,20 +268,6 @@ struct os_file_size_t {
/** Win NT does not allow more than 64 */
static const ulint OS_AIO_N_PENDING_IOS_PER_THREAD = 256;
-/** Modes for aio operations @{ */
-/** Normal asynchronous i/o not for ibuf pages or ibuf bitmap pages */
-static const ulint OS_AIO_NORMAL = 21;
-
-/** Asynchronous i/o for ibuf pages or ibuf bitmap pages */
-static const ulint OS_AIO_IBUF = 22;
-
-/**Calling thread will wait for the i/o to complete,
-and perform IO completion routine itself;
-can be used for any pages, ibuf or non-ibuf. This is used to save
-CPU time, as we can do with fewer thread switches. */
-static const ulint OS_AIO_SYNC = 24;
-/* @} */
-
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
extern ulint os_n_fsyncs;
@@ -728,12 +610,6 @@ The wrapper functions have the prefix of "innodb_". */
# define os_file_close(file) \
pfs_os_file_close_func(file, __FILE__, __LINE__)
-# define os_aio(type, mode, name, file, buf, offset, \
- n, read_only, message1, message2) \
- pfs_os_aio_func(type, mode, name, file, buf, offset, \
- n, read_only, message1, message2, \
- __FILE__, __LINE__)
-
# define os_file_read(type, file, buf, offset, n) \
pfs_os_file_read_func(type, file, buf, offset, n, __FILE__, __LINE__)
@@ -913,44 +789,6 @@ pfs_os_file_read_no_error_handling_func(
const char* src_file,
uint src_line);
-/** NOTE! Please use the corresponding macro os_aio(), not directly this
-function!
-Performance schema wrapper function of os_aio() which requests
-an asynchronous I/O operation.
-@param[in,out] type IO request context
-@param[in] mode IO mode
-@param[in] name Name of the file or path as NUL terminated
- string
-@param[in] file Open file handle
-@param[out] buf buffer where to read
-@param[in] offset file offset where to read
-@param[in] n number of bytes to read
-@param[in] read_only if true read only mode checks are enforced
-@param[in,out] m1 Message for the AIO handler, (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in,out] m2 message for the AIO handler (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in] src_file file name where func invoked
-@param[in] src_line line where the func invoked
-@return DB_SUCCESS if request was queued successfully, FALSE if fail */
-UNIV_INLINE
-dberr_t
-pfs_os_aio_func(
- IORequest& type,
- ulint mode,
- const char* name,
- pfs_os_file_t file,
- void* buf,
- os_offset_t offset,
- ulint n,
- bool read_only,
- fil_node_t* m1,
- void* m2,
- const char* src_file,
- uint src_line);
-
/** NOTE! Please use the corresponding macro os_file_write(), not directly
this function!
This is the performance schema instrumented wrapper function for
@@ -1072,11 +910,6 @@ to original un-instrumented file I/O APIs */
# define os_file_close(file) os_file_close_func(file)
-# define os_aio(type, mode, name, file, buf, offset, \
- n, read_only, message1, message2) \
- os_aio_func(type, mode, name, file, buf, offset, \
- n, read_only, message1, message2)
-
# define os_file_read(type, file, buf, offset, n) \
os_file_read_func(type, file, buf, offset, n)
@@ -1324,50 +1157,14 @@ os_aio_init(
Frees the asynchronous io system. */
void os_aio_free();
-struct os_aio_userdata_t
-{
- fil_node_t* node;
- IORequest type;
- void* message;
-
- os_aio_userdata_t(fil_node_t*node, IORequest type, void*message) :
- node(node), type(type), message(message) {}
-
- /** Construct from tpool::aiocb::m_userdata[] */
- os_aio_userdata_t(const char *buf) { memcpy((void*)this, buf, sizeof*this); }
-};
-/**
-NOTE! Use the corresponding macro os_aio(), not directly this function!
-Requests an asynchronous i/o operation.
-@param[in,out] type IO request context
-@param[in] mode IO mode
-@param[in] name Name of the file or path as NUL terminated
- string
-@param[in] file Open file handle
-@param[out] buf buffer where to read
-@param[in] offset file offset where to read
-@param[in] n number of bytes to read
-@param[in] read_only if true read only mode checks are enforced
-@param[in,out] m1 Message for the AIO handler, (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in,out] m2 message for the AIO handler (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@return DB_SUCCESS or error code */
-dberr_t
-os_aio_func(
- IORequest& type,
- ulint mode,
- const char* name,
- pfs_os_file_t file,
- void* buf,
- os_offset_t offset,
- ulint n,
- bool read_only,
- fil_node_t* m1,
- void* m2);
-
+/** Request a read or write.
+@param type I/O request
+@param buf buffer
+@param offset file offset
+@param n number of bytes
+@retval DB_SUCCESS if request was queued successfully
+@retval DB_IO_ERROR on I/O error */
+dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n);
/** Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
index f950113f3c7..e88f94b8ff3 100644
--- a/storage/innobase/include/os0file.ic
+++ b/storage/innobase/include/os0file.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 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
@@ -201,63 +201,6 @@ pfs_os_file_close_func(
return(result);
}
-/** NOTE! Please use the corresponding macro os_aio(), not directly this
-function!
-Performance schema wrapper function of os_aio() which requests
-an asynchronous i/o operation.
-@param[in,type] type IO request context
-@param[in] mode IO mode
-@param[in] name Name of the file or path as NUL terminated
- string
-@param[in] file Open file handle
-@param[out] buf buffer where to read
-@param[in] offset file offset where to read
-@param[in] n number of bytes to read
-@param[in] read_only if true read only mode checks are enforced
-@param[in,out] m1 Message for the AIO handler, (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in,out] m2 message for the AIO handler (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in] src_file file name where func invoked
-@param[in] src_line line where the func invoked
-@return DB_SUCCESS if request was queued successfully, FALSE if fail */
-UNIV_INLINE
-dberr_t
-pfs_os_aio_func(
- IORequest& type,
- ulint mode,
- const char* name,
- pfs_os_file_t file,
- void* buf,
- os_offset_t offset,
- ulint n,
- bool read_only,
- fil_node_t* m1,
- void* m2,
- const char* src_file,
- uint src_line)
-{
- PSI_file_locker_state state;
- struct PSI_file_locker* locker = NULL;
-
- ut_ad(type.validate());
-
- /* Register the read or write I/O depending on "type" */
- register_pfs_file_io_begin(
- &state, locker, file, n,
- type.is_write() ? PSI_FILE_WRITE : PSI_FILE_READ,
- src_file, src_line);
-
- dberr_t result = os_aio_func(
- type, mode, name, file, buf, offset, n, read_only, m1, m2);
-
- register_pfs_file_io_end(locker, n);
-
- return(result);
-}
-
/** NOTE! Please use the corresponding macro os_file_read(), not directly
this function!
This is the performance schema instrumented wrapper function for
@@ -284,8 +227,6 @@ pfs_os_file_read_func(
PSI_file_locker_state state;
struct PSI_file_locker* locker = NULL;
- ut_ad(type.validate());
-
register_pfs_file_io_begin(
&state, locker, file, n, PSI_FILE_READ, src_file, src_line);
diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h
index 67ee3097274..80a71a41b8d 100644
--- a/storage/innobase/include/os0thread.h
+++ b/storage/innobase/include/os0thread.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, 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
@@ -46,10 +46,6 @@ typedef LPTHREAD_START_ROUTINE os_thread_func_t;
/** Macro for specifying a Windows thread start function. */
#define DECLARE_THREAD(func) WINAPI func
-
-#define os_thread_create(f,a,i) \
- os_thread_create_func(f, a, i)
-
#else
typedef pthread_t os_thread_t;
@@ -60,8 +56,6 @@ extern "C" { typedef void* (*os_thread_func_t)(void*); }
/** Macro for specifying a POSIX thread start function. */
#define DECLARE_THREAD(func) func
-#define os_thread_create(f,a,i) os_thread_create_func(f, a, i)
-
#endif /* _WIN32 */
/* Define a function pointer type to use in a typecast */
@@ -72,9 +66,6 @@ typedef void* (*os_posix_f_t) (void*);
typedef unsigned int mysql_pfs_key_t;
#endif /* HAVE_PSI_INTERFACE */
-/** Number of threads active. */
-extern Atomic_counter<ulint> os_thread_count;
-
/***************************************************************//**
Compares two thread ids for equality.
@return TRUE if equal */
@@ -98,28 +89,10 @@ NOTE: We count the number of threads in os_thread_exit(). A created
thread should always use that to exit so thatthe thread count will be
decremented.
We do not return an error code because if there is one, we crash here. */
-os_thread_t
-os_thread_create_func(
-/*==================*/
- os_thread_func_t func, /*!< in: pointer to function
- from which to start */
- void* arg, /*!< in: argument to start
- function */
- os_thread_id_t* thread_id); /*!< out: id of the created
- thread, or NULL */
-
-/** Waits until the specified thread completes and joins it.
-Its return value is ignored.
-@param[in,out] thread thread to join */
-void
-os_thread_join(
- os_thread_id_t thread);
-
-/** Exits the current thread.
-@param[in] detach if true, the thread will be detached right before
-exiting. If false, another thread is responsible for joining this thread */
-ATTRIBUTE_NORETURN ATTRIBUTE_COLD
-void os_thread_exit(bool detach = true);
+os_thread_t os_thread_create(os_thread_func_t func, void *arg= nullptr);
+
+/** Detach and terminate the current thread. */
+ATTRIBUTE_NORETURN void os_thread_exit();
/*****************************************************************//**
Returns the thread identifier of current thread.
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 2aae5ed6989..a73b9e48755 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -568,7 +568,7 @@ page_get_middle_rec(
Gets the page number.
@return page number */
UNIV_INLINE
-ulint
+uint32_t
page_get_page_no(
/*=============*/
const page_t* page); /*!< in: page */
@@ -577,7 +577,7 @@ page_get_page_no(
Gets the tablespace identifier.
@return space id */
UNIV_INLINE
-ulint
+uint32_t
page_get_space_id(
/*==============*/
const page_t* page); /*!< in: page */
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index ad6fac32b69..2de2ad38080 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -300,7 +300,7 @@ page_get_middle_rec(
Gets the page number.
@return page number */
UNIV_INLINE
-ulint
+uint32_t
page_get_page_no(
/*=============*/
const page_t* page) /*!< in: page */
@@ -314,7 +314,7 @@ page_get_page_no(
Gets the tablespace identifier.
@return space id */
UNIV_INLINE
-ulint
+uint32_t
page_get_space_id(
/*==============*/
const page_t* page) /*!< in: page */
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 651fcb1aa36..af282b378ca 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -35,9 +35,6 @@ Created 5/27/1996 Heikki Tuuri
#include "row0types.h"
#include "pars0types.h"
-/** Mutex protecting the query threads. */
-extern ib_mutex_t que_thr_mutex;
-
/***********************************************************************//**
Creates a query graph fork node.
@return own: fork node */
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 325bb3a2cee..33d8c57a744 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -195,18 +195,9 @@ enum monitor_id_t {
MONITOR_FLUSH_N_TO_FLUSH_REQUESTED,
MONITOR_FLUSH_N_TO_FLUSH_BY_AGE,
- MONITOR_FLUSH_ADAPTIVE_AVG_TIME_SLOT,
- MONITOR_LRU_BATCH_FLUSH_AVG_TIME_SLOT,
-
- MONITOR_FLUSH_ADAPTIVE_AVG_TIME_THREAD,
- MONITOR_LRU_BATCH_FLUSH_AVG_TIME_THREAD,
- MONITOR_FLUSH_ADAPTIVE_AVG_TIME_EST,
- MONITOR_LRU_BATCH_FLUSH_AVG_TIME_EST,
- MONITOR_FLUSH_AVG_TIME,
+ MONITOR_FLUSH_ADAPTIVE_AVG_TIME,
MONITOR_FLUSH_ADAPTIVE_AVG_PASS,
- MONITOR_LRU_BATCH_FLUSH_AVG_PASS,
- MONITOR_FLUSH_AVG_PASS,
MONITOR_LRU_GET_FREE_LOOPS,
MONITOR_LRU_GET_FREE_WAITS,
@@ -234,9 +225,6 @@ enum monitor_id_t {
MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
MONITOR_LRU_BATCH_EVICT_COUNT,
MONITOR_LRU_BATCH_EVICT_PAGES,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_NUM_CALL,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_PER_CALL,
MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT,
MONITOR_LRU_GET_FREE_SEARCH,
MONITOR_LRU_SEARCH_SCANNED,
@@ -326,7 +314,6 @@ enum monitor_id_t {
MONITOR_LSN_CHECKPOINT_AGE,
MONITOR_OVLD_BUF_OLDEST_LSN,
MONITOR_OVLD_MAX_AGE_ASYNC,
- MONITOR_OVLD_MAX_AGE_SYNC,
MONITOR_PENDING_LOG_FLUSH,
MONITOR_PENDING_CHECKPOINT_WRITE,
MONITOR_LOG_IO,
@@ -402,7 +389,6 @@ enum monitor_id_t {
MONITOR_SRV_DICT_LRU_MICROSECOND,
MONITOR_SRV_DICT_LRU_EVICT_COUNT_ACTIVE,
MONITOR_SRV_DICT_LRU_EVICT_COUNT_IDLE,
- MONITOR_SRV_CHECKPOINT_MICROSECOND,
MONITOR_OVLD_SRV_DBLWR_WRITES,
MONITOR_OVLD_SRV_DBLWR_PAGES_WRITTEN,
MONITOR_OVLD_SRV_PAGE_SIZE,
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 57542b32719..44712c5ae66 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -42,7 +42,6 @@ Created 10/10/1995 Heikki Tuuri
#pragma once
#include "log0log.h"
-#include "os0event.h"
#include "que0types.h"
#include "trx0types.h"
#include "fil0fil.h"
@@ -75,8 +74,7 @@ struct srv_stats_t
/** Amount of data written to the log files in bytes */
lsn_ctr_1_t os_log_written;
- /** Number of writes being done to the log files.
- Protected by log_sys.write_mutex. */
+ /** Number of writes being done to the log files */
ulint_ctr_1_t os_log_pending_writes;
/** We increase this counter, when we don't have enough
@@ -102,10 +100,6 @@ struct srv_stats_t
need to make a flush, in order to be able to read or create a page. */
ulint_ctr_1_t buf_pool_wait_free;
- /** Count the number of pages that were written from buffer
- pool to the disk */
- ulint_ctr_1_t buf_pool_flushed;
-
/** Number of buffer pool reads that led to the reading of
a disk page */
ulint_ctr_1_t buf_pool_reads;
@@ -411,7 +405,6 @@ extern unsigned long long srv_stats_modified_counter;
extern my_bool srv_stats_sample_traditional;
extern my_bool srv_use_doublewrite_buf;
-extern ulong srv_doublewrite_batch_size;
extern ulong srv_checksum_algorithm;
extern double srv_max_buf_pool_modified_pct;
@@ -521,7 +514,6 @@ extern ulong srv_buf_dump_status_frequency;
# ifdef UNIV_PFS_THREAD
extern mysql_pfs_key_t page_cleaner_thread_key;
-extern mysql_pfs_key_t recv_writer_thread_key;
extern mysql_pfs_key_t trx_rollback_clean_thread_key;
extern mysql_pfs_key_t thread_pool_thread_key;
@@ -659,19 +651,12 @@ void
srv_export_innodb_status(void);
/*==========================*/
/*******************************************************************//**
-Get current server activity count. We don't hold srv_sys::mutex while
-reading this value as it is only used in heuristics.
+Get current server activity count.
@return activity count. */
ulint
srv_get_activity_count(void);
/*========================*/
-/** Check if there has been any activity.
-@param[in,out] activity_count recent activity count to be returned
-if there is a change
-@return FALSE if no change in activity counter. */
-bool srv_check_activity(ulint *activity_count);
-
/******************************************************************//**
Increment the server activity counter. */
void
@@ -768,7 +753,6 @@ struct export_var_t{
ulint innodb_buffer_pool_read_requests; /*!< buf_pool.stat.n_page_gets */
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
- ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
@@ -822,7 +806,6 @@ struct export_var_t{
ulint innodb_system_rows_inserted; /*!< srv_n_system_rows_inserted */
ulint innodb_system_rows_updated; /*!< srv_n_system_rows_updated */
ulint innodb_system_rows_deleted; /*!< srv_n_system_rows_deleted*/
- ulint innodb_num_open_files; /*!< fil_system_t::n_open */
ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
/** Number of undo tablespace truncation operations */
@@ -895,9 +878,6 @@ struct export_var_t{
struct srv_slot_t{
ibool in_use; /*!< TRUE if this slot
is in use */
- ibool suspended; /*!< TRUE if the thread is
- waiting for the event of this
- slot */
/** time(NULL) when the thread was suspended.
FIXME: Use my_interval_timer() or similar, to avoid bogus
timeouts in lock_wait_check_and_cancel() or lock_wait_suspend_thread()
diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
index 23dc8347129..324e3f0478d 100644
--- a/storage/innobase/include/srv0start.h
+++ b/storage/innobase/include/srv0start.h
@@ -112,11 +112,6 @@ enum srv_shutdown_t {
SRV_SHUTDOWN_INITIATED,
SRV_SHUTDOWN_CLEANUP, /*!< Cleaning up in
logs_empty_and_mark_files_at_shutdown() */
- SRV_SHUTDOWN_FLUSH_PHASE,/*!< At this phase the master and the
- purge threads must have completed their
- work. Once we enter this phase the
- page_cleaner can clean up the buffer
- pool and exit */
SRV_SHUTDOWN_LAST_PHASE,/*!< Last phase after ensuring that
the buffer pool can be freed: flush
all file spaces and close all files */
diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h
index e4186b74370..f9f923f9939 100644
--- a/storage/innobase/include/sync0arr.h
+++ b/storage/innobase/include/sync0arr.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 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
@@ -79,10 +79,9 @@ sync_array_free_cell(
sync_array_t* arr, /*!< in: wait array */
sync_cell_t*& cell); /*!< in: the reserved cell */
-/**********************************************************************//**
-Note that one of the wait objects was signalled. */
-void
-sync_array_object_signalled();
+/** count of how many times an object has been signalled */
+extern ulint sg_count;
+#define sync_array_object_signalled() ++sg_count
/**********************************************************************//**
Prints warnings of long semaphore waits to stderr.
diff --git a/storage/innobase/include/sync0debug.h b/storage/innobase/include/sync0debug.h
index 55ea99cd47b..07e985465e0 100644
--- a/storage/innobase/include/sync0debug.h
+++ b/storage/innobase/include/sync0debug.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+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
@@ -44,10 +44,6 @@ void
sync_check_close();
#ifdef UNIV_DEBUG
-/** Enable sync order checking. */
-void
-sync_check_enable();
-
/** Check if it is OK to acquire the latch.
@param[in] latch latch type */
void
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index e7bf694a4cc..fce598f0930 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -578,12 +578,6 @@ struct rw_lock_t :
/** number of granted SX locks. */
volatile ulint sx_recursive;
- /** This is TRUE if the writer field is RW_LOCK_X_WAIT; 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 */
- bool writer_is_wait_ex;
-
/** The value is typically set to thread id of a writer thread making
normal rw_locks recursive. In case of asynchronous IO, when a non-zero
value of 'pass' is passed then we keep the lock non-recursive.
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 062d7c8a2dc..ce19178a5ad 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -43,37 +43,27 @@ Created 9/5/1995 Heikki Tuuri
instrumentation due to their large number of instances. */
# define PFS_SKIP_BUFFER_MUTEX_RWLOCK
-/* By default, event->mutex will also be excluded from instrumentation */
-# define PFS_SKIP_EVENT_MUTEX
-
#endif /* UNIV_PFS_MUTEX || UNIV_PFS_RWLOCK */
#ifdef UNIV_PFS_MUTEX
/* Key defines to register InnoDB mutexes with performance schema */
extern mysql_pfs_key_t buf_pool_mutex_key;
-extern mysql_pfs_key_t cache_last_read_mutex_key;
extern mysql_pfs_key_t dict_foreign_err_mutex_key;
extern mysql_pfs_key_t dict_sys_mutex_key;
extern mysql_pfs_key_t fil_system_mutex_key;
extern mysql_pfs_key_t flush_list_mutex_key;
-extern mysql_pfs_key_t fts_bg_threads_mutex_key;
extern mysql_pfs_key_t fts_delete_mutex_key;
-extern mysql_pfs_key_t fts_optimize_mutex_key;
extern mysql_pfs_key_t fts_doc_id_mutex_key;
extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key;
-extern mysql_pfs_key_t log_sys_write_mutex_key;
extern mysql_pfs_key_t log_cmdq_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key;
-extern mysql_pfs_key_t mutex_list_mutex_key;
extern mysql_pfs_key_t recalc_pool_mutex_key;
-extern mysql_pfs_key_t page_cleaner_mutex_key;
extern mysql_pfs_key_t purge_sys_pq_mutex_key;
extern mysql_pfs_key_t recv_sys_mutex_key;
-extern mysql_pfs_key_t recv_writer_mutex_key;
extern mysql_pfs_key_t rtr_active_mutex_key;
extern mysql_pfs_key_t rtr_match_mutex_key;
extern mysql_pfs_key_t rtr_path_mutex_key;
@@ -84,7 +74,6 @@ extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
extern mysql_pfs_key_t rw_lock_debug_mutex_key;
# endif /* UNIV_DEBUG */
extern mysql_pfs_key_t rw_lock_list_mutex_key;
-extern mysql_pfs_key_t rw_lock_mutex_key;
extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
extern mysql_pfs_key_t srv_monitor_file_mutex_key;
@@ -95,10 +84,7 @@ extern mysql_pfs_key_t trx_pool_manager_mutex_key;
extern mysql_pfs_key_t lock_mutex_key;
extern mysql_pfs_key_t lock_wait_mutex_key;
extern mysql_pfs_key_t trx_sys_mutex_key;
-extern mysql_pfs_key_t srv_sys_mutex_key;
extern mysql_pfs_key_t srv_threads_mutex_key;
-extern mysql_pfs_key_t event_mutex_key;
-extern mysql_pfs_key_t event_manager_mutex_key;
extern mysql_pfs_key_t sync_array_mutex_key;
extern mysql_pfs_key_t thread_mutex_key;
extern mysql_pfs_key_t row_drop_list_mutex_key;
@@ -122,7 +108,6 @@ extern mysql_pfs_key_t trx_i_s_cache_lock_key;
extern mysql_pfs_key_t trx_purge_latch_key;
extern mysql_pfs_key_t index_tree_rw_lock_key;
extern mysql_pfs_key_t index_online_log_key;
-extern mysql_pfs_key_t dict_table_stats_key;
extern mysql_pfs_key_t trx_sys_rw_lock_key;
#endif /* UNIV_PFS_RWLOCK */
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index a4584937e70..feb1e3b45ef 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -186,18 +186,8 @@ enum latch_level_t {
RW_LOCK_X,
RW_LOCK_NOT_LOCKED,
- SYNC_MONITOR_MUTEX,
-
SYNC_ANY_LATCH,
- SYNC_DOUBLEWRITE,
-
- SYNC_BUF_FLUSH_LIST,
-
- SYNC_BUF_PAGE_HASH,
-
- SYNC_BUF_POOL,
-
SYNC_POOL,
SYNC_POOL_MANAGER,
@@ -207,17 +197,10 @@ enum latch_level_t {
SYNC_FTS_TOKENIZE,
SYNC_FTS_OPTIMIZE,
- SYNC_FTS_BG_THREADS,
SYNC_FTS_CACHE_INIT,
SYNC_RECV,
- SYNC_LOG_FLUSH_ORDER,
- SYNC_LOG,
- SYNC_LOG_WRITE,
- SYNC_PAGE_CLEANER,
SYNC_PURGE_QUEUE,
SYNC_TRX_SYS_HEADER,
- SYNC_REC_LOCK,
- SYNC_THREADS,
SYNC_TRX,
SYNC_RW_TRX_HASH_ELEMENT,
SYNC_READ_VIEW,
@@ -258,12 +241,8 @@ enum latch_level_t {
SYNC_DICT_OPERATION,
- SYNC_TRX_I_S_LAST_READ,
-
SYNC_TRX_I_S_RWLOCK,
- SYNC_RECV_WRITER,
-
/** Level is varying. Only used with buffer pool page locks, which
do not have a fixed level, but instead have their level set after
the page is locked; see e.g. ibuf_bitmap_get_map_page(). */
@@ -278,34 +257,21 @@ enum latch_level_t {
};
/** Each latch has an ID. This id is used for creating the latch and to look
-up its meta-data. See sync0debug.c. */
+up its meta-data. See sync0debug.cc. */
enum latch_id_t {
LATCH_ID_NONE = 0,
- LATCH_ID_BUF_POOL,
- LATCH_ID_CACHE_LAST_READ,
LATCH_ID_DICT_FOREIGN_ERR,
LATCH_ID_DICT_SYS,
- LATCH_ID_FILE_FORMAT_MAX,
LATCH_ID_FIL_SYSTEM,
- LATCH_ID_FLUSH_LIST,
- LATCH_ID_FTS_BG_THREADS,
LATCH_ID_FTS_DELETE,
- LATCH_ID_FTS_OPTIMIZE,
LATCH_ID_FTS_DOC_ID,
LATCH_ID_FTS_PLL_TOKENIZE,
LATCH_ID_IBUF_BITMAP,
LATCH_ID_IBUF,
LATCH_ID_IBUF_PESSIMISTIC_INSERT,
- LATCH_ID_LOG_SYS,
- LATCH_ID_LOG_WRITE,
- LATCH_ID_LOG_FLUSH_ORDER,
- LATCH_ID_LIST,
- LATCH_ID_MUTEX_LIST,
- LATCH_ID_PAGE_CLEANER,
LATCH_ID_PURGE_SYS_PQ,
LATCH_ID_RECALC_POOL,
LATCH_ID_RECV_SYS,
- LATCH_ID_RECV_WRITER,
LATCH_ID_REDO_RSEG,
LATCH_ID_NOREDO_RSEG,
LATCH_ID_RW_LOCK_DEBUG,
@@ -313,28 +279,18 @@ enum latch_id_t {
LATCH_ID_RTR_MATCH_MUTEX,
LATCH_ID_RTR_PATH_MUTEX,
LATCH_ID_RW_LOCK_LIST,
- LATCH_ID_RW_LOCK_MUTEX,
LATCH_ID_SRV_INNODB_MONITOR,
LATCH_ID_SRV_MISC_TMPFILE,
LATCH_ID_SRV_MONITOR_FILE,
- LATCH_ID_BUF_DBLWR,
LATCH_ID_TRX_POOL,
LATCH_ID_TRX_POOL_MANAGER,
LATCH_ID_TRX,
LATCH_ID_LOCK_SYS,
LATCH_ID_LOCK_SYS_WAIT,
LATCH_ID_TRX_SYS,
- LATCH_ID_SRV_SYS,
LATCH_ID_SRV_SYS_TASKS,
LATCH_ID_PAGE_ZIP_STAT_PER_INDEX,
- LATCH_ID_EVENT_MANAGER,
- LATCH_ID_EVENT_MUTEX,
LATCH_ID_SYNC_ARRAY_MUTEX,
- LATCH_ID_OS_AIO_READ_MUTEX,
- LATCH_ID_OS_AIO_WRITE_MUTEX,
- LATCH_ID_OS_AIO_LOG_MUTEX,
- LATCH_ID_OS_AIO_IBUF_MUTEX,
- LATCH_ID_OS_AIO_SYNC_MUTEX,
LATCH_ID_ROW_DROP_LIST,
LATCH_ID_INDEX_ONLINE_LOG,
LATCH_ID_WORK_QUEUE,
@@ -342,7 +298,6 @@ enum latch_id_t {
LATCH_ID_BUF_BLOCK_LOCK,
LATCH_ID_BUF_BLOCK_DEBUG,
LATCH_ID_DICT_OPERATION,
- LATCH_ID_CHECKPOINT,
LATCH_ID_FIL_SPACE,
LATCH_ID_FTS_CACHE,
LATCH_ID_FTS_CACHE_INIT,
@@ -351,10 +306,6 @@ enum latch_id_t {
LATCH_ID_IBUF_INDEX_TREE,
LATCH_ID_INDEX_TREE,
LATCH_ID_DICT_TABLE_STATS,
- LATCH_ID_HASH_TABLE_RW_LOCK,
- LATCH_ID_BUF_CHUNK_MAP_LATCH,
- LATCH_ID_SYNC_DEBUG_MUTEX,
- LATCH_ID_SCRUB_STAT_MUTEX,
LATCH_ID_DEFRAGMENT_MUTEX,
LATCH_ID_BTR_DEFRAGMENT_MUTEX,
LATCH_ID_FIL_CRYPT_STAT_MUTEX,
@@ -362,8 +313,7 @@ enum latch_id_t {
LATCH_ID_FIL_CRYPT_THREADS_MUTEX,
LATCH_ID_RW_TRX_HASH_ELEMENT,
LATCH_ID_READ_VIEW,
- LATCH_ID_TEST_MUTEX,
- LATCH_ID_MAX = LATCH_ID_TEST_MUTEX
+ LATCH_ID_MAX = LATCH_ID_READ_VIEW
};
#ifndef UNIV_INNOCHECKSUM
@@ -643,10 +593,10 @@ public:
}
/** Iterate over the counters */
- template <typename Callback>
- void iterate(Callback& callback) const
- UNIV_NOTHROW
+ template<typename C> void iterate(const C& callback) UNIV_NOTHROW
{
+ m_mutex.enter();
+
Counters::const_iterator end = m_counters.end();
for (Counters::const_iterator it = m_counters.begin();
@@ -655,6 +605,8 @@ public:
callback(*it);
}
+
+ m_mutex.exit();
}
/** Disable the monitoring */
@@ -1014,9 +966,7 @@ struct sync_checker : public sync_check_functor_t
{
if (some_allowed) {
switch (level) {
- case SYNC_RECV_WRITER:
- /* This only happens in
- recv_apply_hashed_log_recs. */
+ case SYNC_FSP:
case SYNC_DICT:
case SYNC_DICT_OPERATION:
case SYNC_FTS_CACHE:
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index 937e05dfba6..a3ccc90b630 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -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
@@ -37,7 +37,7 @@ Created 3/26/1996 Heikki Tuuri
@return rollback segment header, page x-latched */
UNIV_INLINE
buf_block_t*
-trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr);
+trx_rsegf_get(fil_space_t* space, uint32_t page_no, mtr_t* mtr);
/** Gets a newly created rollback segment header.
@param[in] space space where placed
@@ -48,7 +48,7 @@ UNIV_INLINE
buf_block_t*
trx_rsegf_get_new(
ulint space,
- ulint page_no,
+ uint32_t page_no,
mtr_t* mtr);
/** Create a rollback segment header.
@@ -106,10 +106,10 @@ struct trx_rseg_t {
fil_space_t* space;
/** page number of the rollback segment header */
- ulint page_no;
+ uint32_t page_no;
/** current size in pages */
- ulint curr_size;
+ uint32_t curr_size;
/*--------------------------------------------------------*/
/* Fields for undo logs */
diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic
index e0e8c175a5d..b293d9f1ae1 100644
--- a/storage/innobase/include/trx0rseg.ic
+++ b/storage/innobase/include/trx0rseg.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2013, 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
@@ -34,7 +34,7 @@ Created 3/26/1996 Heikki Tuuri
@return rollback segment header, page x-latched */
UNIV_INLINE
buf_block_t*
-trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr)
+trx_rsegf_get(fil_space_t* space, uint32_t page_no, mtr_t* mtr)
{
ut_ad(space == fil_system.sys_space || space == fil_system.temp_space
|| srv_is_undo_tablespace(space->id)
@@ -56,7 +56,7 @@ UNIV_INLINE
buf_block_t*
trx_rsegf_get_new(
ulint space,
- ulint page_no,
+ uint32_t page_no,
mtr_t* mtr)
{
buf_block_t* block;
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index acb10428108..9fe6fcfa262 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -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
@@ -46,10 +46,9 @@ Created 3/26/1996 Heikki Tuuri
/** Checks if a page address is the trx sys header page.
@param[in] page_id page id
@return true if trx sys header page */
-inline bool trx_sys_hdr_page(const page_id_t& page_id)
+inline bool trx_sys_hdr_page(const page_id_t page_id)
{
- return(page_id.space() == TRX_SYS_SPACE
- && page_id.page_no() == TRX_SYS_PAGE_NO);
+ return page_id == page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO);
}
/*****************************************************************//**
@@ -340,9 +339,6 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
constexpr uint32_t TRX_SYS_DOUBLEWRITE_MAGIC_N= 536853855;
/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
constexpr uint32_t TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N= 1783657386;
-
-/** Size of the doublewrite block in pages */
-#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
/* @} */
trx_t* current_trx();
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index 37421930b9b..9325f39a309 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -327,8 +327,6 @@ struct trx_undo_t {
(IB_ID_MAX if the undo log is empty) */
buf_block_t* guess_block; /*!< guess for the buffer block where
the top page might reside */
- ulint withdraw_clock; /*!< the withdraw clock value of the
- buffer pool when guess_block was stored */
/** @return whether the undo log is empty */
bool empty() const { return top_undo_no == IB_ID_MAX; }
diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h
index 414c00dfae8..2fc864d49a2 100644
--- a/storage/innobase/include/ut0mem.h
+++ b/storage/innobase/include/ut0mem.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 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
@@ -27,8 +27,7 @@ Created 5/30/1994 Heikki Tuuri
#ifndef ut0mem_h
#define ut0mem_h
-#include "os0event.h"
-#include "ut0mutex.h"
+#include "univ.i"
/********************************************************************
Concatenate 3 strings.*/
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
index 04ec10cc379..294304e672a 100644
--- a/storage/innobase/include/ut0mutex.h
+++ b/storage/innobase/include/ut0mutex.h
@@ -131,16 +131,10 @@ public:
/* Some of the slots will be null in non-debug mode */
- if (*it == NULL) {
- continue;
- }
-
- latch_meta_t* latch_meta = *it;
-
- bool ret = callback(*latch_meta);
-
- if (!ret) {
- return(ret);
+ if (latch_meta_t* l= *it) {
+ if (!callback(*l)) {
+ return false;
+ }
}
}
diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h
index 5a895f4ea3c..347622989dd 100644
--- a/storage/innobase/include/ut0wqueue.h
+++ b/storage/innobase/include/ut0wqueue.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2014, 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
@@ -46,9 +46,6 @@ struct ib_wqueue_t
ib_mutex_t mutex;
/** Work item list */
ib_list_t* items;
- /** event we use to signal additions to list;
- os_event_set() and os_event_reset() are protected by the mutex */
- os_event_t event;
};
/****************************************************************//**
@@ -79,23 +76,6 @@ ib_wqueue_add(ib_wqueue_t* wq, void* item, mem_heap_t* heap,
@return whether the queue is empty */
bool ib_wqueue_is_empty(ib_wqueue_t* wq);
-/****************************************************************//**
-Wait for a work item to appear in the queue.
-@return work item */
-void*
-ib_wqueue_wait(
-/*===========*/
- ib_wqueue_t* wq); /*!< in: work queue */
-
-/********************************************************************
-Wait for a work item to appear in the queue for specified time. */
-void*
-ib_wqueue_timedwait(
-/*================*/
- /* out: work item or NULL on timeout*/
- ib_wqueue_t* wq, /* in: work queue */
- ulint wait_in_usecs); /* in: wait time in micro seconds */
-
/********************************************************************
Return first item on work queue or NULL if queue is empty
@return work item or NULL */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 494f4a07036..24a2249f3f6 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -4670,7 +4670,7 @@ static void lock_rec_block_validate(const page_id_t page_id)
discard or rebuild a tablespace do hold an exclusive table
lock, which would conflict with any locks referring to the
tablespace from other transactions. */
- if (fil_space_t* space = fil_space_acquire(page_id.space())) {
+ if (fil_space_t* space = fil_space_t::get(page_id.space())) {
dberr_t err = DB_SUCCESS;
mtr_start(&mtr);
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index 7278e0f353d..b606228b1fe 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -53,10 +53,9 @@ lock_wait_table_print(void)
fprintf(stderr,
"Slot %lu:"
- " in use %lu, susp %lu, timeout %lu, time %lu\n",
+ " in use %lu, timeout %lu, time %lu\n",
(ulong) i,
(ulong) slot->in_use,
- (ulong) slot->suspended,
slot->wait_timeout,
(ulong) difftime(time(NULL), slot->suspend_time));
}
@@ -154,7 +153,6 @@ lock_wait_table_reserve_slot(
}
os_event_reset(slot->event);
- slot->suspended = TRUE;
slot->suspend_time = time(NULL);
slot->wait_timeout = wait_timeout;
@@ -443,7 +441,6 @@ lock_wait_check_and_cancel(
{
ut_ad(lock_wait_mutex_own());
ut_ad(slot->in_use);
- ut_ad(slot->suspended);
double wait_time = difftime(time(NULL), slot->suspend_time);
trx_t* trx = thr_get_trx(slot->thr);
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index e8a7a5aa88c..ba4c8bb8d62 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -50,6 +50,7 @@ Created 12/9/1995 Heikki Tuuri
#include "trx0trx.h"
#include "trx0roll.h"
#include "srv0mon.h"
+#include "sync0sync.h"
#include "buf0dump.h"
#include "log0sync.h"
@@ -63,14 +64,6 @@ to the InnoDB redo log. */
/** Redo log system */
log_t log_sys;
-/* These control how often we print warnings if the last checkpoint is too
-old */
-static bool log_has_printed_chkp_warning = false;
-static time_t log_last_warning_time;
-
-static bool log_has_printed_chkp_margine_warning = false;
-static time_t log_last_margine_warning_time;
-
/* A margin for free space in the log buffer before a log entry is catenated */
#define LOG_BUF_WRITE_MARGIN (4 * OS_FILE_LOG_BLOCK_SIZE)
@@ -79,31 +72,6 @@ static time_t log_last_margine_warning_time;
#define LOG_BUF_FLUSH_MARGIN (LOG_BUF_WRITE_MARGIN \
+ (4U << srv_page_size_shift))
-/* This parameter controls asynchronous making of a new checkpoint; the value
-should be bigger than LOG_POOL_PREFLUSH_RATIO_SYNC */
-
-#define LOG_POOL_CHECKPOINT_RATIO_ASYNC 32
-
-/* This parameter controls synchronous preflushing of modified buffer pages */
-#define LOG_POOL_PREFLUSH_RATIO_SYNC 16
-
-/* The same ratio for asynchronous preflushing; this value should be less than
-the previous */
-#define LOG_POOL_PREFLUSH_RATIO_ASYNC 8
-
-/** Return the oldest modified LSN in buf_pool.flush_list,
-or the latest LSN if all pages are clean.
-@return LSN of oldest modification */
-static lsn_t log_buf_pool_get_oldest_modification()
-{
- ut_ad(log_mutex_own());
- log_flush_order_mutex_enter();
- lsn_t lsn= buf_pool.get_oldest_modification();
- log_flush_order_mutex_exit();
-
- return lsn ? lsn : log_sys.get_lsn();
-}
-
/** Extends the log buffer.
@param[in] len requested minimum size in bytes */
void log_buffer_extend(ulong len)
@@ -116,11 +84,11 @@ void log_buffer_extend(ulong len)
(ut_malloc_dontdump(new_buf_size, PSI_INSTRUMENT_ME));
TRASH_ALLOC(new_flush_buf, new_buf_size);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (len <= srv_log_buffer_size) {
/* Already extended enough by the others */
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
ut_free_dodump(new_buf, new_buf_size);
ut_free_dodump(new_flush_buf, new_buf_size);
return;
@@ -142,7 +110,7 @@ void log_buffer_extend(ulong len)
log_sys.max_buf_free = new_buf_size / LOG_BUF_FLUSH_RATIO
- LOG_BUF_FLUSH_MARGIN;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
ut_free_dodump(old_buf, old_buf_size);
ut_free_dodump(old_flush_buf, old_buf_size);
@@ -151,276 +119,6 @@ void log_buffer_extend(ulong len)
<< new_buf_size << ".";
}
-/** Calculate actual length in redo buffer and file including
-block header and trailer.
-@param[in] len length to write
-@return actual length to write including header and trailer. */
-static inline
-ulint
-log_calculate_actual_len(
- ulint len)
-{
- ut_ad(log_mutex_own());
-
- const ulint framing_size = log_sys.framing_size();
- /* actual length stored per block */
- const ulint len_per_blk = OS_FILE_LOG_BLOCK_SIZE - framing_size;
-
- /* actual data length in last block already written */
- ulint extra_len = (log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE);
-
- ut_ad(extra_len >= LOG_BLOCK_HDR_SIZE);
- extra_len -= LOG_BLOCK_HDR_SIZE;
-
- /* total extra length for block header and trailer */
- extra_len = ((len + extra_len) / len_per_blk) * framing_size;
-
- return(len + extra_len);
-}
-
-/** Check margin not to overwrite transaction log from the last checkpoint.
-If would estimate the log write to exceed the log_capacity,
-waits for the checkpoint is done enough.
-@param[in] len length of the data to be written */
-
-void
-log_margin_checkpoint_age(
- ulint len)
-{
- ulint margin = log_calculate_actual_len(len);
-
- ut_ad(log_mutex_own());
-
- if (margin > log_sys.log_capacity) {
- /* return with warning output to avoid deadlock */
- if (!log_has_printed_chkp_margine_warning
- || difftime(time(NULL),
- log_last_margine_warning_time) > 15) {
- log_has_printed_chkp_margine_warning = true;
- log_last_margine_warning_time = time(NULL);
-
- ib::error() << "The transaction log file is too"
- " small for the single transaction log (size="
- << len << "). So, the last checkpoint age"
- " might exceed the log capacity "
- << log_sys.log_capacity << ".";
- }
-
- return;
- }
-
- /* Our margin check should ensure that we never reach this condition.
- Try to do checkpoint once. We cannot keep waiting here as it might
- result in hang in case the current mtr has latch on oldest lsn */
- const lsn_t lsn = log_sys.get_lsn();
-
- if (lsn - log_sys.last_checkpoint_lsn + margin
- > log_sys.log_capacity) {
- /* The log write of 'len' might overwrite the transaction log
- after the last checkpoint. Makes checkpoint. */
-
- const bool flushed_enough = lsn
- - log_buf_pool_get_oldest_modification() + margin
- <= log_sys.log_capacity;
-
- log_sys.set_check_flush_or_checkpoint();
- log_mutex_exit();
-
- DEBUG_SYNC_C("margin_checkpoint_age_rescue");
-
- if (!flushed_enough) {
- os_thread_sleep(100000);
- }
- log_checkpoint();
-
- log_mutex_enter();
- }
-
- return;
-}
-
-/** Open the log for log_write_low. The log must be closed with log_close.
-@param[in] len length of the data to be written
-@return start lsn of the log record */
-lsn_t
-log_reserve_and_open(
- ulint len)
-{
- ulint len_upper_limit;
-#ifdef UNIV_DEBUG
- ulint count = 0;
-#endif /* UNIV_DEBUG */
-
-loop:
- ut_ad(log_mutex_own());
-
- /* Calculate an upper limit for the space the string may take in the
- log buffer */
-
- len_upper_limit = LOG_BUF_WRITE_MARGIN + srv_log_write_ahead_size
- + (5 * len) / 4;
-
- if (log_sys.buf_free + len_upper_limit > srv_log_buffer_size) {
- log_mutex_exit();
-
- DEBUG_SYNC_C("log_buf_size_exceeded");
-
- /* Not enough free space, do a write of the log buffer */
- log_sys.initiate_write(false);
-
- srv_stats.log_waits.inc();
-
- ut_ad(++count < 50);
-
- log_mutex_enter();
- goto loop;
- }
-
- return(log_sys.get_lsn());
-}
-
-/************************************************************//**
-Writes to the log the string given. It is assumed that the caller holds the
-log mutex. */
-void
-log_write_low(
-/*==========*/
- const byte* str, /*!< in: string */
- ulint str_len) /*!< in: string length */
-{
- ulint len;
-
- ut_ad(log_mutex_own());
- const ulint trailer_offset = log_sys.trailer_offset();
-part_loop:
- /* Calculate a part length */
-
- ulint data_len = (log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;
-
- if (data_len <= trailer_offset) {
-
- /* The string fits within the current log block */
-
- len = str_len;
- } else {
- data_len = trailer_offset;
-
- len = trailer_offset
- - log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE;
- }
-
- memcpy(log_sys.buf + log_sys.buf_free, str, len);
-
- str_len -= len;
- str = str + len;
-
- byte* log_block = static_cast<byte*>(
- ut_align_down(log_sys.buf + log_sys.buf_free,
- OS_FILE_LOG_BLOCK_SIZE));
-
- log_block_set_data_len(log_block, data_len);
- lsn_t lsn = log_sys.get_lsn();
-
- if (data_len == trailer_offset) {
- /* This block became full */
- log_block_set_data_len(log_block, OS_FILE_LOG_BLOCK_SIZE);
- log_block_set_checkpoint_no(log_block,
- log_sys.next_checkpoint_no);
- len += log_sys.framing_size();
-
- lsn += len;
-
- /* Initialize the next block header */
- log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, lsn);
- } else {
- lsn += len;
- }
-
- log_sys.set_lsn(lsn);
- log_sys.buf_free += len;
-
- ut_ad(log_sys.buf_free <= size_t{srv_log_buffer_size});
-
- if (str_len > 0) {
- goto part_loop;
- }
-
- srv_stats.log_write_requests.inc();
-}
-
-/************************************************************//**
-Closes the log.
-@return lsn */
-lsn_t
-log_close(void)
-/*===========*/
-{
- byte* log_block;
- ulint first_rec_group;
- lsn_t oldest_lsn;
- lsn_t lsn;
- lsn_t checkpoint_age;
-
- ut_ad(log_mutex_own());
-
- lsn = log_sys.get_lsn();
-
- log_block = static_cast<byte*>(
- ut_align_down(log_sys.buf + log_sys.buf_free,
- OS_FILE_LOG_BLOCK_SIZE));
-
- first_rec_group = log_block_get_first_rec_group(log_block);
-
- if (first_rec_group == 0) {
- /* We initialized a new log block which was not written
- full by the current mtr: the next mtr log record group
- will start within this block at the offset data_len */
-
- log_block_set_first_rec_group(
- log_block, log_block_get_data_len(log_block));
- }
-
- if (log_sys.buf_free > log_sys.max_buf_free) {
- log_sys.set_check_flush_or_checkpoint();
- }
-
- checkpoint_age = lsn - log_sys.last_checkpoint_lsn;
-
- if (checkpoint_age >= log_sys.log_capacity) {
- DBUG_EXECUTE_IF(
- "print_all_chkp_warnings",
- log_has_printed_chkp_warning = false;);
-
- if (!log_has_printed_chkp_warning
- || difftime(time(NULL), log_last_warning_time) > 15) {
-
- log_has_printed_chkp_warning = true;
- log_last_warning_time = time(NULL);
-
- ib::error() << "The age of the last checkpoint is "
- << checkpoint_age
- << ", which exceeds the log capacity "
- << log_sys.log_capacity << ".";
- }
- }
-
- if (checkpoint_age <= log_sys.max_modified_age_sync ||
- log_sys.check_flush_or_checkpoint()) {
- goto function_exit;
- }
-
- oldest_lsn = log_buf_pool_get_oldest_modification();
-
- if (!oldest_lsn
- || lsn - oldest_lsn > log_sys.max_modified_age_sync
- || checkpoint_age > log_sys.max_checkpoint_age_async) {
- log_sys.set_check_flush_or_checkpoint();
- }
-function_exit:
-
- return(lsn);
-}
-
/** Calculate the recommended highest values for lsn - last_checkpoint_lsn
and lsn - buf_pool.get_oldest_modification().
@param[in] file_size requested innodb_log_file_size
@@ -459,20 +157,14 @@ log_set_capacity(ulonglong file_size)
margin = smallest_capacity - free;
margin = margin - margin / 10; /* Add still some extra safety */
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
log_sys.log_capacity = smallest_capacity;
- log_sys.max_modified_age_async = margin
- - margin / LOG_POOL_PREFLUSH_RATIO_ASYNC;
- log_sys.max_modified_age_sync = margin
- - margin / LOG_POOL_PREFLUSH_RATIO_SYNC;
-
- log_sys.max_checkpoint_age_async = margin - margin
- / LOG_POOL_CHECKPOINT_RATIO_ASYNC;
+ log_sys.max_modified_age_async = margin - margin / 8;
log_sys.max_checkpoint_age = margin;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(true);
}
@@ -484,14 +176,14 @@ void log_t::create()
ut_ad(!is_initialised());
m_initialised= true;
- mutex_create(LATCH_ID_LOG_SYS, &mutex);
- mutex_create(LATCH_ID_LOG_FLUSH_ORDER, &log_flush_order_mutex);
+ mysql_mutex_init(log_sys_mutex_key, &mutex, nullptr);
+ mysql_mutex_init(log_flush_order_mutex_key, &flush_order_mutex, nullptr);
/* Start the lsn from one log block from zero: this way every
log record has a non-zero start lsn, a fact which we will use */
set_lsn(LOG_START_LSN + LOG_BLOCK_HDR_SIZE);
- set_flushed_lsn(0);
+ set_flushed_lsn(LOG_START_LSN + LOG_BLOCK_HDR_SIZE);
ut_ad(srv_log_buffer_size >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_ad(srv_log_buffer_size >= 4U << srv_page_size_shift);
@@ -516,8 +208,6 @@ void log_t::create()
n_log_ios_old= 0;
log_capacity= 0;
max_modified_age_async= 0;
- max_modified_age_sync= 0;
- max_checkpoint_age_async= 0;
max_checkpoint_age= 0;
next_checkpoint_no= 0;
next_checkpoint_lsn= 0;
@@ -931,10 +621,11 @@ loop:
}
/** Flush the recently written changes to the log file.
-and invoke log_mutex_enter(). */
+and invoke mysql_mutex_lock(&log_sys.mutex). */
static void log_write_flush_to_disk_low(lsn_t lsn)
{
- log_sys.log.flush();
+ if (!log_sys.log.writes_are_durable())
+ log_sys.log.flush();
ut_a(lsn >= log_sys.get_flushed_lsn());
log_sys.set_flushed_lsn(lsn);
}
@@ -946,7 +637,7 @@ static inline
void
log_buffer_switch()
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(log_write_lock_own());
size_t area_end = ut_calc_align<size_t>(
@@ -970,18 +661,18 @@ which is the "write" part of log_write_up_to().
This function does not flush anything.
-Note : the caller must have log_mutex locked, and this
+Note : the caller must have log_sys.mutex locked, and this
mutex is released in the function.
*/
static void log_write(bool rotate_key)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(!recv_no_log_write);
lsn_t write_lsn;
if (log_sys.buf_free == log_sys.buf_next_to_write) {
/* Nothing to write */
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return;
}
@@ -1018,7 +709,7 @@ static void log_write(bool rotate_key)
log_sys.log.set_fields(log_sys.write_lsn);
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
/* Erase the end of the last log block. */
memset(write_buf + end_offset, 0,
~end_offset & (OS_FILE_LOG_BLOCK_SIZE - 1));
@@ -1109,7 +800,7 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key)
if (write_lock.acquire(lsn) == group_commit_lock::ACQUIRED)
{
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
lsn_t write_lsn= log_sys.get_lsn();
write_lock.set_pending(write_lsn);
@@ -1127,12 +818,7 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key)
/* Flush the highest written lsn.*/
auto flush_lsn = write_lock.value();
flush_lock.set_pending(flush_lsn);
-
- if (!log_sys.log.writes_are_durable())
- {
- log_write_flush_to_disk_low(flush_lsn);
- }
-
+ log_write_flush_to_disk_low(flush_lsn);
flush_lock.release(flush_lsn);
innobase_mysql_log_notify(flush_lsn);
@@ -1153,91 +839,28 @@ log_buffer_flush_to_disk(
Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */
-static
-void
-log_flush_margin(void)
-/*==================*/
+ATTRIBUTE_COLD static void log_flush_margin()
{
lsn_t lsn = 0;
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (log_sys.buf_free > log_sys.max_buf_free) {
/* We can write during flush */
lsn = log_sys.get_lsn();
}
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (lsn) {
log_write_up_to(lsn, false);
}
}
-/** Advances the smallest lsn for which there are unflushed dirty blocks in the
-buffer pool.
-NOTE: this function may only be called if the calling thread owns no
-synchronization objects!
-@param[in] new_oldest try to advance oldest_modified_lsn at least to
-this lsn
-@return false if there was a flush batch of the same type running,
-which means that we could not start this flush batch */
-static bool log_preflush_pool_modified_pages(lsn_t new_oldest)
-{
- bool success;
-
- if (recv_recovery_is_on()) {
- /* If the recovery is running, we must first apply all
- log records to their respective file pages to get the
- right modify lsn values to these pages: otherwise, there
- might be pages on disk which are not yet recovered to the
- current lsn, and even after calling this function, we could
- not know how up-to-date the disk version of the database is,
- and we could not make a new checkpoint on the basis of the
- info on the buffer pool only. */
- recv_sys.apply(true);
- }
-
- if (new_oldest == LSN_MAX
- || !buf_page_cleaner_is_active
- || srv_is_being_started) {
-
- ulint n_pages;
-
- success = buf_flush_lists(ULINT_MAX, new_oldest, &n_pages);
-
- buf_flush_wait_batch_end(false);
-
- if (!success) {
- MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS);
- }
-
- MONITOR_INC_VALUE_CUMULATIVE(
- MONITOR_FLUSH_SYNC_TOTAL_PAGE,
- MONITOR_FLUSH_SYNC_COUNT,
- MONITOR_FLUSH_SYNC_PAGES,
- n_pages);
- } else {
- /* better to wait for flushed by page cleaner */
-
- if (srv_flush_sync) {
- /* wake page cleaner for IO burst */
- buf_flush_request_force(new_oldest);
- }
-
- buf_flush_wait_flushed(new_oldest);
-
- success = true;
- }
-
- return(success);
-}
-
-/** Write checkpoint info to the log header and invoke log_mutex_exit().
+/** Write checkpoint info to the log header and release log_sys.mutex.
@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */
-void log_write_checkpoint_info(lsn_t end_lsn)
+ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
{
- ut_ad(log_mutex_own());
ut_ad(!srv_read_only_mode);
ut_ad(end_lsn == 0 || end_lsn >= log_sys.next_checkpoint_lsn);
ut_ad(end_lsn <= log_sys.get_lsn());
@@ -1273,7 +896,7 @@ void log_write_checkpoint_info(lsn_t end_lsn)
++log_sys.n_pending_checkpoint_writes;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
/* Note: We alternate the physical place of the checkpoint info.
See the (next_checkpoint_no & 1) below. */
@@ -1284,7 +907,7 @@ void log_write_checkpoint_info(lsn_t end_lsn)
log_sys.log.flush();
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
--log_sys.n_pending_checkpoint_writes;
ut_ad(log_sys.n_pending_checkpoint_writes == 0);
@@ -1302,197 +925,43 @@ void log_write_checkpoint_info(lsn_t end_lsn)
DBUG_EXECUTE_IF("crash_after_checkpoint", DBUG_SUICIDE(););
- log_mutex_exit();
-}
-
-/** Make a checkpoint. Note that this function does not flush dirty
-blocks from the buffer pool: it only checks what is lsn of the oldest
-modification in the pool, and writes information about the lsn in
-log file. Use log_make_checkpoint() to flush also the pool.
-@return true if success, false if a checkpoint write was already running */
-bool log_checkpoint()
-{
- lsn_t oldest_lsn;
-
- ut_ad(!srv_read_only_mode);
-
- DBUG_EXECUTE_IF("no_checkpoint",
- /* We sleep for a long enough time, forcing
- the checkpoint doesn't happen any more. */
- os_thread_sleep(360000000););
-
- if (recv_recovery_is_on()) {
- recv_sys.apply(true);
- }
-
- switch (srv_file_flush_method) {
- case SRV_NOSYNC:
- break;
- case SRV_O_DSYNC:
- case SRV_FSYNC:
- case SRV_LITTLESYNC:
- case SRV_O_DIRECT:
- case SRV_O_DIRECT_NO_FSYNC:
-#ifdef _WIN32
- case SRV_ALL_O_DIRECT_FSYNC:
-#endif
- fil_flush_file_spaces();
- }
-
- log_mutex_enter();
-
- ut_ad(!recv_no_log_write);
- oldest_lsn = log_buf_pool_get_oldest_modification();
-
- /* Because log also contains headers and dummy log records,
- log_buf_pool_get_oldest_modification() will return log_sys.lsn
- if the buffer pool contains no dirty buffers.
- We must make sure that the log is flushed up to that lsn.
- If there are dirty buffers in the buffer pool, then our
- write-ahead-logging algorithm ensures that the log has been
- flushed up to oldest_lsn. */
-
- ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn);
- if (oldest_lsn
- > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) {
- /* Some log has been written since the previous checkpoint. */
- } else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
- /* MariaDB startup expects the redo log file to be
- logically empty (not even containing a MLOG_CHECKPOINT record)
- after a clean shutdown. Perform an extra checkpoint at
- shutdown. */
- } else {
- /* Do nothing, because nothing was logged (other than
- a FILE_CHECKPOINT marker) since the previous checkpoint. */
- log_mutex_exit();
- return(true);
- }
- /* Repeat the FILE_MODIFY records after the checkpoint, in
- case some log records between the checkpoint and log_sys.lsn
- need them. Finally, write a FILE_CHECKPOINT marker. Redo log
- apply expects to see a FILE_CHECKPOINT after the checkpoint,
- except on clean shutdown, where the log will be empty after
- the checkpoint.
- It is important that we write out the redo log before any
- further dirty pages are flushed to the tablespace files. At
- this point, because log_mutex_own(), mtr_commit() in other
- threads will be blocked, and no pages can be added to the
- flush lists. */
- lsn_t flush_lsn = oldest_lsn;
- const lsn_t end_lsn = log_sys.get_lsn();
- const bool do_write
- = srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
- || flush_lsn != end_lsn;
-
- if (fil_names_clear(flush_lsn, do_write)) {
- flush_lsn = log_sys.get_lsn();
- ut_ad(flush_lsn >= end_lsn + SIZE_OF_FILE_CHECKPOINT);
- }
-
- log_mutex_exit();
-
- log_write_up_to(flush_lsn, true, true);
-
- log_mutex_enter();
-
- ut_ad(log_sys.get_flushed_lsn() >= flush_lsn);
- ut_ad(flush_lsn >= oldest_lsn);
-
- if (log_sys.last_checkpoint_lsn >= oldest_lsn) {
- log_mutex_exit();
- return(true);
- }
-
- if (log_sys.n_pending_checkpoint_writes > 0) {
- /* A checkpoint write is running */
- log_mutex_exit();
-
- return(false);
- }
-
- log_sys.next_checkpoint_lsn = oldest_lsn;
- log_write_checkpoint_info(end_lsn);
- ut_ad(!log_mutex_own());
-
- return(true);
-}
-
-/** Make a checkpoint */
-void log_make_checkpoint()
-{
- /* Preflush pages synchronously */
-
- while (!log_preflush_pool_modified_pages(LSN_MAX)) {
- /* Flush as much as we can */
- }
-
- while (!log_checkpoint()) {
- /* Force a checkpoint */
- }
+ mysql_mutex_unlock(&log_sys.mutex);
}
/****************************************************************//**
-Tries to establish a big enough margin of free space in the log groups, such
+Tries to establish a big enough margin of free space in the log, such
that a new log entry can be catenated without an immediate need for a
checkpoint. NOTE: this function may only be called if the calling thread
owns no synchronization objects! */
-static
-void
-log_checkpoint_margin(void)
-/*=======================*/
+ATTRIBUTE_COLD static void log_checkpoint_margin()
{
- ib_uint64_t advance;
- bool success;
-loop:
- advance = 0;
-
- log_mutex_enter();
- ut_ad(!recv_no_log_write);
-
- if (!log_sys.check_flush_or_checkpoint()) {
- log_mutex_exit();
- return;
- }
-
- const lsn_t oldest_lsn = log_buf_pool_get_oldest_modification();
- const lsn_t lsn = log_sys.get_lsn();
- const lsn_t age = lsn - oldest_lsn;
-
- if (age > log_sys.max_modified_age_sync) {
-
- /* A flush is urgent: we have to do a synchronous preflush */
- advance = age - log_sys.max_modified_age_sync;
- }
-
- const lsn_t checkpoint_age = lsn - log_sys.last_checkpoint_lsn;
-
- ut_ad(log_sys.max_checkpoint_age >= log_sys.max_checkpoint_age_async);
- const bool do_checkpoint
- = checkpoint_age > log_sys.max_checkpoint_age_async;
-
- if (checkpoint_age <= log_sys.max_checkpoint_age) {
- log_sys.set_check_flush_or_checkpoint(false);
- }
-
- log_mutex_exit();
-
- if (advance) {
- lsn_t new_oldest = oldest_lsn + advance;
-
- success = log_preflush_pool_modified_pages(new_oldest);
-
- /* If the flush succeeded, this thread has done its part
- and can proceed. If it did not succeed, there was another
- thread doing a flush at the same time. */
- if (!success) {
- log_sys.set_check_flush_or_checkpoint();
- goto loop;
- }
- }
+ while (log_sys.check_flush_or_checkpoint())
+ {
+ mysql_mutex_lock(&log_sys.mutex);
+ ut_ad(!recv_no_log_write);
- if (do_checkpoint) {
- log_checkpoint();
- }
+ if (!log_sys.check_flush_or_checkpoint())
+ {
+func_exit:
+ mysql_mutex_unlock(&log_sys.mutex);
+ return;
+ }
+
+ const lsn_t lsn= log_sys.get_lsn();
+ const lsn_t checkpoint= log_sys.last_checkpoint_lsn;
+ const lsn_t sync_lsn= checkpoint + log_sys.max_checkpoint_age;
+ if (lsn <= sync_lsn)
+ {
+ log_sys.set_check_flush_or_checkpoint(false);
+ goto func_exit;
+ }
+
+ mysql_mutex_unlock(&log_sys.mutex);
+
+ /* We must wait to prevent the tail of the log overwriting the head. */
+ buf_flush_wait_flushed(std::min(sync_lsn, checkpoint + (1U << 20)));
+ os_thread_sleep(10000); /* Sleep 10ms to avoid a thundering herd */
+ }
}
/**
@@ -1500,7 +969,7 @@ Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
objects! */
-void log_check_margins()
+ATTRIBUTE_COLD void log_check_margins()
{
do
{
@@ -1514,7 +983,7 @@ void log_check_margins()
extern void buf_resize_shutdown();
/** Make a checkpoint at the latest lsn on shutdown. */
-void logs_empty_and_mark_files_at_shutdown()
+ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown()
{
lsn_t lsn;
ulint count = 0;
@@ -1553,14 +1022,6 @@ loop:
ut_ad(log_sys.is_initialised() || !srv_was_started);
ut_ad(fil_system.is_initialised() || !srv_was_started);
- if (!srv_read_only_mode) {
- if (recv_sys.flush_start) {
- /* This is in case recv_writer_thread was never
- started, or buf_flush_page_cleaner
- failed to notice its termination. */
- os_event_set(recv_sys.flush_start);
- }
- }
#define COUNT_INTERVAL 600U
#define CHECK_INTERVAL 100000U
os_thread_sleep(CHECK_INTERVAL);
@@ -1622,37 +1083,33 @@ wait_suspend_loop:
goto wait_suspend_loop;
}
- buf_load_dump_end();
-
- srv_shutdown_state = SRV_SHUTDOWN_FLUSH_PHASE;
+ if (buf_page_cleaner_is_active) {
+ thread_name = "page cleaner thread";
+ mysql_cond_signal(&buf_pool.do_flush_list);
+ goto wait_suspend_loop;
+ }
- /* At this point only page_cleaner should be active. We wait
- here to let it complete the flushing of the buffer pools
- before proceeding further. */
+ buf_load_dump_end();
- count = 0;
- service_manager_extend_timeout(COUNT_INTERVAL * CHECK_INTERVAL/1000000 * 2,
- "Waiting for page cleaner");
- while (buf_page_cleaner_is_active) {
- ++count;
- os_thread_sleep(CHECK_INTERVAL);
- if (srv_print_verbose_log && count > COUNT_INTERVAL) {
- service_manager_extend_timeout(COUNT_INTERVAL * CHECK_INTERVAL/1000000 * 2,
- "Waiting for page cleaner");
- ib::info() << "Waiting for page_cleaner to "
- "finish flushing of buffer pool";
- /* This is a workaround to avoid the InnoDB hang
- when OS datetime changed backwards */
- os_event_set(buf_flush_event);
+ if (!buf_pool.is_initialised()) {
+ ut_ad(!srv_was_started);
+ } else if (ulint pending_io = buf_pool.io_pending()) {
+ if (srv_print_verbose_log && count > 600) {
+ ib::info() << "Waiting for " << pending_io << " buffer"
+ " page I/Os to complete";
count = 0;
}
+
+ goto loop;
+ } else {
+ buf_flush_buffer_pool();
}
if (log_sys.is_initialised()) {
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
const ulint n_write = log_sys.n_pending_checkpoint_writes;
const ulint n_flush = log_sys.pending_flushes;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (n_write || n_flush) {
if (srv_print_verbose_log && count > 600) {
@@ -1666,18 +1123,6 @@ wait_suspend_loop:
}
}
- if (!buf_pool.is_initialised()) {
- ut_ad(!srv_was_started);
- } else if (ulint pending_io = buf_pool.io_pending()) {
- if (srv_print_verbose_log && count > 600) {
- ib::info() << "Waiting for " << pending_io << " buffer"
- " page I/Os to complete";
- count = 0;
- }
-
- goto loop;
- }
-
if (srv_fast_shutdown == 2 || !srv_was_started) {
if (!srv_read_only_mode && srv_was_started) {
ib::info() << "MySQL has requested a very fast"
@@ -1707,7 +1152,7 @@ wait_suspend_loop:
"ensuring dirty buffer pool are written to log");
log_make_checkpoint();
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
lsn = log_sys.get_lsn();
@@ -1716,7 +1161,7 @@ wait_suspend_loop:
+ SIZE_OF_FILE_CHECKPOINT;
ut_ad(lsn >= log_sys.last_checkpoint_lsn);
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (lsn_changed) {
goto loop;
@@ -1773,16 +1218,21 @@ log_print(
double time_elapsed;
time_t current_time;
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
+
+ const lsn_t lsn= log_sys.get_lsn();
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ const lsn_t pages_flushed = buf_pool.get_oldest_modification(lsn);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
fprintf(file,
"Log sequence number " LSN_PF "\n"
"Log flushed up to " LSN_PF "\n"
"Pages flushed up to " LSN_PF "\n"
"Last checkpoint at " LSN_PF "\n",
- log_sys.get_lsn(),
+ lsn,
log_sys.get_flushed_lsn(),
- log_buf_pool_get_oldest_modification(),
+ pages_flushed,
log_sys.last_checkpoint_lsn);
current_time = time(NULL);
@@ -1808,7 +1258,7 @@ log_print(
log_sys.n_log_ios_old = log_sys.n_log_ios;
log_sys.last_printout_time = current_time;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
}
/**********************************************************************//**
@@ -1834,8 +1284,8 @@ void log_t::close()
ut_free_dodump(flush_buf, srv_log_buffer_size);
flush_buf = NULL;
- mutex_free(&mutex);
- mutex_free(&log_flush_order_mutex);
+ mysql_mutex_destroy(&mutex);
+ mysql_mutex_destroy(&flush_order_mutex);
recv_sys.close();
}
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 2cb798b61fc..c5cf21bf59a 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -90,13 +90,6 @@ is bigger than the lsn we are able to scan up to, that is an indication that
the recovery failed and the database may be corrupt. */
static lsn_t recv_max_page_lsn;
-#ifdef UNIV_PFS_THREAD
-mysql_pfs_key_t recv_writer_thread_key;
-#endif /* UNIV_PFS_THREAD */
-
-/** Is recv_writer_thread active? */
-bool recv_writer_thread_active;
-
/** Stored physical log record with logical LSN (@see log_t::FORMAT_10_5) */
struct log_phys_t : public log_rec_t
{
@@ -542,7 +535,7 @@ struct file_name_t {
fil_status status;
/** FSP_SIZE of tablespace */
- ulint size = 0;
+ uint32_t size = 0;
/** Freed pages of tablespace */
range_set freed_ranges;
@@ -915,7 +908,6 @@ same_space:
void recv_sys_t::close()
{
ut_ad(this == &recv_sys);
- ut_ad(!recv_writer_thread_active);
if (is_initialised())
{
@@ -924,9 +916,6 @@ void recv_sys_t::close()
clear();
ut_d(mutex_exit(&mutex));
- os_event_destroy(flush_start);
- os_event_destroy(flush_end);
-
if (buf)
{
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
@@ -934,7 +923,6 @@ void recv_sys_t::close()
}
last_stored_lsn= 0;
- mutex_free(&writer_mutex);
mutex_free(&mutex);
}
@@ -944,80 +932,13 @@ void recv_sys_t::close()
close_files();
}
-/******************************************************************//**
-recv_writer thread tasked with flushing dirty pages from the buffer
-pools.
-@return a dummy parameter */
-extern "C"
-os_thread_ret_t
-DECLARE_THREAD(recv_writer_thread)(
-/*===============================*/
- void* arg MY_ATTRIBUTE((unused)))
- /*!< in: a dummy parameter required by
- os_thread_create */
-{
- my_thread_init();
- ut_ad(!srv_read_only_mode);
-
-#ifdef UNIV_PFS_THREAD
- pfs_register_thread(recv_writer_thread_key);
-#endif /* UNIV_PFS_THREAD */
-
-#ifdef UNIV_DEBUG_THREAD_CREATION
- ib::info() << "recv_writer thread running, id "
- << os_thread_pf(os_thread_get_curr_id());
-#endif /* UNIV_DEBUG_THREAD_CREATION */
-
- while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
-
- /* Wait till we get a signal to clean the LRU list.
- Bounded by max wait time of 100ms. */
- int64_t sig_count = os_event_reset(buf_flush_event);
- os_event_wait_time_low(buf_flush_event, 100000, sig_count);
-
- mutex_enter(&recv_sys.writer_mutex);
-
- if (!recv_recovery_is_on()) {
- mutex_exit(&recv_sys.writer_mutex);
- break;
- }
-
- /* Flush pages from end of LRU if required */
- os_event_reset(recv_sys.flush_end);
- recv_sys.flush_lru = true;
- os_event_set(recv_sys.flush_start);
- os_event_wait(recv_sys.flush_end);
-
- mutex_exit(&recv_sys.writer_mutex);
- }
-
- recv_writer_thread_active = false;
-
- my_thread_end();
- /* We count the number of threads in os_thread_exit().
- A created thread should always use that to exit and not
- use return() to exit. */
- os_thread_exit();
-
- OS_THREAD_DUMMY_RETURN;
-}
-
/** Initialize the redo log recovery subsystem. */
void recv_sys_t::create()
{
ut_ad(this == &recv_sys);
ut_ad(!is_initialised());
- ut_ad(!flush_start);
- ut_ad(!flush_end);
mutex_create(LATCH_ID_RECV_SYS, &mutex);
- mutex_create(LATCH_ID_RECV_WRITER, &writer_mutex);
- if (!srv_read_only_mode) {
- flush_start = os_event_create(0);
- flush_end = os_event_create(0);
- }
-
- flush_lru = true;
apply_log_recs = false;
apply_batch_on = false;
@@ -1068,20 +989,12 @@ void recv_sys_t::debug_free()
ut_ad(is_initialised());
mutex_enter(&mutex);
+ recovery_on= false;
pages.clear();
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
buf= nullptr;
- /* wake page cleaner up to progress */
- if (!srv_read_only_mode)
- {
- ut_ad(!recv_recovery_is_on());
- ut_ad(!recv_writer_thread_active);
- os_event_reset(buf_flush_event);
- os_event_set(flush_start);
- }
-
mutex_exit(&mutex);
}
@@ -1173,7 +1086,7 @@ bool log_t::file::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn)
{
ulint len;
bool success = true;
- ut_ad(log_sys.mutex.is_owned());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(!(*start_lsn % OS_FILE_LOG_BLOCK_SIZE));
ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE));
byte* buf = log_sys.buf;
@@ -1296,7 +1209,7 @@ recv_synchronize_groups()
if (!srv_read_only_mode) {
log_write_checkpoint_info(0);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
}
}
@@ -1826,7 +1739,7 @@ static void store_freed_or_init_rec(page_id_t page_id, bool freed)
or corruption was noticed */
bool recv_sys_t::parse(lsn_t checkpoint_lsn, store_t *store, bool apply)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(mutex_own(&mutex));
ut_ad(parse_start_lsn);
ut_ad(log_sys.is_physical());
@@ -2147,7 +2060,14 @@ same_page:
const bool is_init= (b & 0x70) <= INIT_PAGE;
switch (*store) {
case STORE_IF_EXISTS:
- if (!fil_space_get_size(space_id))
+ if (fil_space_t *space= fil_space_t::get(space_id))
+ {
+ const auto size= space->get_size();
+ space->release();
+ if (!size)
+ continue;
+ }
+ else
continue;
/* fall through */
case STORE_YES:
@@ -2392,7 +2312,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
if (fil_space_t* s = space
? space
- : fil_space_acquire(block->page.id().space())) {
+ : fil_space_t::get(block->page.id().space())) {
switch (a) {
case log_phys_t::APPLIED_TO_FSP_HEADER:
s->flags = mach_read_from_4(
@@ -2431,7 +2351,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
fil_crypt_parse(s, b);
}
- if (s != space) {
+ if (!space) {
s->release();
}
}
@@ -2458,9 +2378,9 @@ set_start_lsn:
}
buf_block_modify_clock_inc(block);
- log_flush_order_mutex_enter();
+ mysql_mutex_lock(&log_sys.flush_order_mutex);
buf_flush_note_modification(block, start_lsn, end_lsn);
- log_flush_order_mutex_exit();
+ mysql_mutex_unlock(&log_sys.flush_order_mutex);
} else if (free_page && init) {
/* There have been no operations that modify the page.
Any buffered changes must not be merged. A subsequent
@@ -2554,12 +2474,12 @@ page number.
@param[in] page_id page id */
static void recv_read_in_area(page_id_t page_id)
{
- ulint page_nos[RECV_READ_AHEAD_AREA];
+ uint32_t page_nos[RECV_READ_AHEAD_AREA];
compile_time_assert(ut_is_2pow(RECV_READ_AHEAD_AREA));
page_id.set_page_no(ut_2pow_round(page_id.page_no(),
RECV_READ_AHEAD_AREA));
const ulint up_limit = page_id.page_no() + RECV_READ_AHEAD_AREA;
- ulint* p = page_nos;
+ uint32_t* p = page_nos;
for (recv_sys_t::map::iterator i= recv_sys.pages.lower_bound(page_id);
i != recv_sys.pages.end()
@@ -2574,7 +2494,7 @@ static void recv_read_in_area(page_id_t page_id)
if (p != page_nos) {
mutex_exit(&recv_sys.mutex);
- buf_read_recv_pages(FALSE, page_id.space(), page_nos,
+ buf_read_recv_pages(page_id.space(), page_nos,
ulint(p - page_nos));
mutex_enter(&recv_sys.mutex);
}
@@ -2584,9 +2504,11 @@ static void recv_read_in_area(page_id_t page_id)
@param page_id page identifier
@param p iterator pointing to page_id
@param mtr mini-transaction
+@param b pre-allocated buffer pool block
@return whether the page was successfully initialized */
inline buf_block_t *recv_sys_t::recover_low(const page_id_t page_id,
- map::iterator &p, mtr_t &mtr)
+ map::iterator &p, mtr_t &mtr,
+ buf_block_t *b)
{
ut_ad(mutex_own(&mutex));
ut_ad(p->first == page_id);
@@ -2598,24 +2520,25 @@ inline buf_block_t *recv_sys_t::recover_low(const page_id_t page_id,
if (end_lsn < i.lsn)
DBUG_LOG("ib_log", "skip log for page " << page_id
<< " LSN " << end_lsn << " < " << i.lsn);
- else if (fil_space_t *space= fil_space_acquire_for_io(page_id.space()))
+ else if (fil_space_t *space= fil_space_t::get(page_id.space()))
{
mtr.start();
mtr.set_log_mode(MTR_LOG_NO_REDO);
- block= buf_page_create(space, page_id.page_no(), space->zip_size(), &mtr);
- p= recv_sys.pages.find(page_id);
- if (p == recv_sys.pages.end())
+ block= buf_page_create(space, page_id.page_no(), space->zip_size(), &mtr,
+ b);
+ if (UNIV_UNLIKELY(block != b))
{
/* The page happened to exist in the buffer pool, or it was just
being read in. Before buf_page_get_with_no_latch() returned to
buf_page_create(), all changes must have been applied to the
page already. */
+ ut_ad(recv_sys.pages.find(page_id) == recv_sys.pages.end());
mtr.commit();
block= nullptr;
}
else
{
- ut_ad(&recs == &p->second);
+ ut_ad(&recs == &recv_sys.pages.find(page_id)->second);
i.created= true;
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
recv_recover_page(block, mtr, p, space, &i);
@@ -2624,7 +2547,7 @@ inline buf_block_t *recv_sys_t::recover_low(const page_id_t page_id,
map::iterator r= p++;
recv_sys.pages.erase(r);
}
- space->release_for_io();
+ space->release();
}
return block;
@@ -2635,6 +2558,7 @@ inline buf_block_t *recv_sys_t::recover_low(const page_id_t page_id,
@return whether the page was successfully initialized */
buf_block_t *recv_sys_t::recover_low(const page_id_t page_id)
{
+ buf_block_t *free_block= buf_LRU_get_free_block(false);
buf_block_t *block= nullptr;
mutex_enter(&mutex);
@@ -2643,10 +2567,13 @@ buf_block_t *recv_sys_t::recover_low(const page_id_t page_id)
if (p != pages.end() && p->second.state == page_recv_t::RECV_WILL_NOT_READ)
{
mtr_t mtr;
- block= recover_low(page_id, p, mtr);
+ block= recover_low(page_id, p, mtr, free_block);
+ ut_ad(!block || block == free_block);
}
mutex_exit(&mutex);
+ if (UNIV_UNLIKELY(!block))
+ buf_pool.free_block(free_block);
return block;
}
@@ -2672,7 +2599,9 @@ void recv_sys_t::apply(bool last_batch)
mutex_enter(&mutex);
}
- ut_ad(!last_batch == log_mutex_own());
+#ifdef SAFE_MUTEX
+ DBUG_ASSERT(!last_batch == mysql_mutex_is_owner(&log_sys.mutex));
+#endif /* SAFE_MUTEX */
recv_no_ibuf_operations = !last_batch ||
srv_operation == SRV_OPERATION_RESTORE ||
@@ -2701,6 +2630,8 @@ void recv_sys_t::apply(bool last_batch)
trim(page_id_t(id + srv_undo_space_id_start, t.pages), t.lsn);
}
+ buf_block_t *free_block= buf_LRU_get_free_block(false);
+
for (map::iterator p= pages.begin(); p != pages.end(); )
{
const page_id_t page_id= p->first;
@@ -2713,7 +2644,14 @@ void recv_sys_t::apply(bool last_batch)
p++;
continue;
case page_recv_t::RECV_WILL_NOT_READ:
- recover_low(page_id, p, mtr);
+ if (UNIV_LIKELY(!!recover_low(page_id, p, mtr, free_block)))
+ {
+ mutex_exit(&mutex);
+ free_block= buf_LRU_get_free_block(false);
+ mutex_enter(&mutex);
+next_page:
+ p= pages.lower_bound(page_id);
+ }
continue;
case page_recv_t::RECV_NOT_PROCESSED:
mtr.start();
@@ -2739,9 +2677,11 @@ void recv_sys_t::apply(bool last_batch)
continue;
}
- p= pages.lower_bound(page_id);
+ goto next_page;
}
+ buf_pool.free_block(free_block);
+
/* Wait until all the pages have been processed */
while (!pages.empty())
{
@@ -2759,35 +2699,29 @@ void recv_sys_t::apply(bool last_batch)
}
}
- if (!last_batch)
+ if (last_batch)
+ /* We skipped this in buf_page_create(). */
+ mlog_init.mark_ibuf_exist(mtr);
+ else
{
- /* Flush all the file pages to disk and invalidate them in buf_pool */
- mutex_exit(&mutex);
- log_mutex_exit();
-
- /* Stop the recv_writer thread from issuing any LRU flush batches. */
- mutex_enter(&writer_mutex);
+ mlog_init.reset();
+ mysql_mutex_unlock(&log_sys.mutex);
+ }
- /* Wait for any currently run batch to end. */
- buf_flush_wait_LRU_batch_end();
+ mysql_mutex_assert_not_owner(&log_sys.mutex);
+ mutex_exit(&mutex);
- os_event_reset(flush_end);
- flush_lru= false;
- os_event_set(flush_start);
- os_event_wait(flush_end);
+ /* Instead of flushing, last_batch could sort the buf_pool.flush_list
+ in ascending order of buf_page_t::oldest_modification. */
+ buf_flush_sync();
+ if (!last_batch)
+ {
buf_pool_invalidate();
-
- /* Allow batches from recv_writer thread. */
- mutex_exit(&writer_mutex);
-
- log_mutex_enter();
- mutex_enter(&mutex);
- mlog_init.reset();
+ mysql_mutex_lock(&log_sys.mutex);
}
- else
- /* We skipped this in buf_page_create(). */
- mlog_init.mark_ibuf_exist(mtr);
+
+ mutex_enter(&mutex);
ut_d(after_apply= true);
clear();
@@ -3004,8 +2938,8 @@ static bool recv_scan_log_recs(
}
ib::info() << "Starting crash recovery from"
- " checkpoint LSN="
- << recv_sys.scanned_lsn;
+ " checkpoint LSN=" << checkpoint_lsn
+ << "," << recv_sys.scanned_lsn;
}
/* We were able to find more log data: add it to the
@@ -3120,7 +3054,6 @@ recv_group_scan_log_recs(
recv_sys.recovered_lsn = *contiguous_lsn;
recv_sys.scanned_checkpoint_no = 0;
ut_ad(recv_max_page_lsn == 0);
- ut_ad(last_phase || !recv_writer_thread_active);
mutex_exit(&recv_sys.mutex);
lsn_t start_lsn;
@@ -3343,7 +3276,6 @@ recv_init_crash_recovery_spaces(bool rescan, bool& missing_tablespace)
}
/** Start recovering from a redo log checkpoint.
-@see recv_recovery_from_checkpoint_finish
@param[in] flush_lsn FIL_PAGE_FILE_FLUSH_LSN
of first system tablespace page
@return error code or DB_SUCCESS */
@@ -3361,14 +3293,10 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
ut_ad(srv_operation == SRV_OPERATION_NORMAL
|| srv_operation == SRV_OPERATION_RESTORE
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT);
- ut_d(mutex_enter(&buf_pool.flush_list_mutex));
+ ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex));
ut_ad(UT_LIST_GET_LEN(buf_pool.LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool.unzip_LRU) == 0);
- ut_d(mutex_exit(&buf_pool.flush_list_mutex));
-
- /* Initialize red-black tree for fast insertions into the
- flush_list during recovery process. */
- buf_flush_init_flush_rbt();
+ ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex));
if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) {
@@ -3379,14 +3307,14 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
recv_sys.recovery_on = true;
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
recv_sys.recovered_lsn = log_sys.get_lsn();
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(err);
}
@@ -3410,7 +3338,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
contiguous_lsn = checkpoint_lsn;
switch (log_sys.log.format) {
case 0:
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return DB_SUCCESS;
default:
if (end_lsn == 0) {
@@ -3421,7 +3349,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
break;
}
recv_sys.found_corrupt_log = true;
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
@@ -3439,12 +3367,12 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
ut_ad(!recv_sys.found_corrupt_fs);
if (srv_read_only_mode && recv_needed_recovery) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(DB_READ_ONLY);
}
if (recv_sys.found_corrupt_log && !srv_force_recovery) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
ib::warn() << "Log scan aborted at LSN " << contiguous_lsn;
return(DB_ERROR);
}
@@ -3452,7 +3380,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if (recv_sys.mlog_checkpoint_lsn == 0) {
lsn_t scan_lsn = log_sys.log.scanned_lsn;
if (!srv_read_only_mode && scan_lsn != checkpoint_lsn) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
ib::error err;
err << "Missing FILE_CHECKPOINT";
if (end_lsn) {
@@ -3471,7 +3399,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if ((recv_sys.found_corrupt_log && !srv_force_recovery)
|| recv_sys.found_corrupt_fs) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
}
@@ -3512,7 +3440,7 @@ completed:
if (srv_read_only_mode) {
ib::error() << "innodb_read_only"
" prevents crash recovery";
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(DB_READ_ONLY);
}
@@ -3521,6 +3449,11 @@ completed:
}
log_sys.set_lsn(recv_sys.recovered_lsn);
+ if (UNIV_LIKELY(log_sys.get_flushed_lsn() < recv_sys.recovered_lsn)) {
+ /* This may already have been set by create_log_file()
+ if no logs existed when the server started up. */
+ log_sys.set_flushed_lsn(recv_sys.recovered_lsn);
+ }
if (recv_needed_recovery) {
bool missing_tablespace = false;
@@ -3529,7 +3462,7 @@ completed:
rescan, missing_tablespace);
if (err != DB_SUCCESS) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(err);
}
@@ -3559,7 +3492,7 @@ completed:
rescan, missing_tablespace);
if (err != DB_SUCCESS) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return err;
}
@@ -3569,16 +3502,11 @@ completed:
recv_sys.parse_start_lsn = checkpoint_lsn;
if (srv_operation == SRV_OPERATION_NORMAL) {
- buf_dblwr_process();
+ buf_dblwr.recover();
}
ut_ad(srv_force_recovery <= SRV_FORCE_NO_UNDO_LOG_SCAN);
- /* Spawn the background thread to flush dirty pages
- from the buffer pools. */
- recv_writer_thread_active = true;
- os_thread_create(recv_writer_thread, 0, 0);
-
if (rescan) {
contiguous_lsn = checkpoint_lsn;
@@ -3588,7 +3516,7 @@ completed:
if ((recv_sys.found_corrupt_log
&& !srv_force_recovery)
|| recv_sys.found_corrupt_fs) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
}
@@ -3609,7 +3537,7 @@ completed:
}
if (recv_sys.recovered_lsn < checkpoint_lsn) {
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
ib::error() << "Recovered only to lsn:"
<< recv_sys.recovered_lsn << " checkpoint_lsn: " << checkpoint_lsn;
@@ -3647,7 +3575,7 @@ completed:
mutex_exit(&recv_sys.mutex);
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
recv_lsn_checks_on = true;
@@ -3658,45 +3586,6 @@ completed:
return(DB_SUCCESS);
}
-/** Complete recovery from a checkpoint. */
-void
-recv_recovery_from_checkpoint_finish(void)
-{
- /* Make sure that the recv_writer thread is done. This is
- required because it grabs various mutexes and we want to
- ensure that when we enable sync_order_checks there is no
- mutex currently held by any thread. */
- mutex_enter(&recv_sys.writer_mutex);
-
- /* Free the resources of the recovery system */
- recv_sys.recovery_on = false;
-
- /* By acquring the mutex we ensure that the recv_writer thread
- won't trigger any more LRU batches. Now wait for currently
- in progress batches to finish. */
- buf_flush_wait_LRU_batch_end();
-
- mutex_exit(&recv_sys.writer_mutex);
-
- ulint count = 0;
- while (recv_writer_thread_active) {
- ++count;
- os_thread_sleep(100000);
- if (srv_print_verbose_log && count > 600) {
- ib::info() << "Waiting for recv_writer to"
- " finish flushing of buffer pool";
- count = 0;
- }
- }
-
- recv_sys.debug_free();
-
- /* Free up the flush_rbt. */
- buf_flush_free_flush_rbt();
- /* Enable innodb_sync_debug checks */
- ut_d(sync_check_enable());
-}
-
bool recv_dblwr_t::validate_page(const page_id_t page_id,
const byte *page,
const fil_space_t *space,
@@ -3779,7 +3668,7 @@ byte *recv_dblwr_t::find_page(const page_id_t page_id,
if (lsn <= max_lsn ||
!validate_page(page_id, page, space, tmp_buf))
{
- /* Mark processed for subsequent iterations in buf_dblwr_process() */
+ /* Mark processed for subsequent iterations in buf_dblwr_t::recover() */
memset(page + FIL_PAGE_LSN, 0, 8);
continue;
}
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 17b524f610f..dede92ad755 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -214,7 +214,7 @@ static void memo_slot_release(mtr_memo_slot_t *slot)
case MTR_MEMO_SPACE_X_LOCK:
{
fil_space_t *space= static_cast<fil_space_t*>(slot->object);
- space->committed_size= space->size;
+ space->set_committed_size();
rw_lock_x_unlock(&space->latch);
}
break;
@@ -256,7 +256,7 @@ struct ReleaseLatches {
case MTR_MEMO_SPACE_X_LOCK:
{
fil_space_t *space= static_cast<fil_space_t*>(slot->object);
- space->committed_size= space->size;
+ space->set_committed_size();
rw_lock_x_unlock(&space->latch);
}
break;
@@ -350,17 +350,6 @@ struct ReleaseBlocks
}
};
-/** Write the block contents to the REDO log */
-struct mtr_write_log_t {
- /** Append a block to the redo log buffer.
- @return whether the appending should continue */
- bool operator()(const mtr_buf_t::block_t* block) const
- {
- log_write_low(block->begin(), block->used());
- return(true);
- }
-};
-
/** Start a mini-transaction. */
void mtr_t::start()
{
@@ -411,20 +400,20 @@ void mtr_t::commit()
{
ut_ad(!srv_read_only_mode || m_log_mode == MTR_LOG_NO_REDO);
- lsn_t start_lsn;
+ std::pair<lsn_t,bool> lsns;
if (const ulint len= prepare_write())
- start_lsn= finish_write(len);
+ lsns= finish_write(len);
else
- start_lsn= m_commit_lsn;
+ lsns= { m_commit_lsn, false };
if (m_made_dirty)
- log_flush_order_mutex_enter();
+ mysql_mutex_lock(&log_sys.flush_order_mutex);
/* It is now safe to release the log mutex because the
flush_order mutex will ensure that we are the first one
to insert into the flush list. */
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (m_freed_pages)
{
@@ -453,12 +442,18 @@ void mtr_t::commit()
}
m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks>
- (ReleaseBlocks(start_lsn, m_commit_lsn,
+ (ReleaseBlocks(lsns.first, m_commit_lsn,
m_memo)));
if (m_made_dirty)
- log_flush_order_mutex_exit();
+ mysql_mutex_unlock(&log_sys.flush_order_mutex);
m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>());
+
+ if (lsns.second)
+ buf_flush_ahead(m_commit_lsn);
+
+ if (m_made_dirty)
+ srv_stats.log_write_requests.inc();
}
else
m_memo.for_each_block_in_reverse(CIterate<ReleaseAll>());
@@ -469,12 +464,12 @@ void mtr_t::commit()
/** Commit a mini-transaction that did not modify any pages,
but generated some redo log on a higher level, such as
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
-The caller must invoke log_mutex_enter() and log_mutex_exit().
+The caller must hold log_sys.mutex.
This is to be used at log_checkpoint().
@param[in] checkpoint_lsn log checkpoint LSN, or 0 */
void mtr_t::commit_files(lsn_t checkpoint_lsn)
{
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(is_active());
ut_ad(!is_inside_ibuf());
ut_ad(m_log_mode == MTR_LOG_ALL);
@@ -496,6 +491,7 @@ void mtr_t::commit_files(lsn_t checkpoint_lsn)
}
finish_write(m_log.size());
+ srv_stats.log_write_requests.inc();
release_resources();
if (checkpoint_lsn) {
@@ -621,6 +617,200 @@ mtr_t::release_page(const void* ptr, mtr_memo_type_t type)
ut_ad(0);
}
+static bool log_margin_warned;
+static time_t log_margin_warn_time;
+static bool log_close_warned;
+static time_t log_close_warn_time;
+
+/** Check margin not to overwrite transaction log from the last checkpoint.
+If would estimate the log write to exceed the log_capacity,
+waits for the checkpoint is done enough.
+@param len length of the data to be written */
+static void log_margin_checkpoint_age(ulint len)
+{
+ const ulint framing_size= log_sys.framing_size();
+ /* actual length stored per block */
+ const ulint len_per_blk= OS_FILE_LOG_BLOCK_SIZE - framing_size;
+
+ /* actual data length in last block already written */
+ ulint extra_len= log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE;
+
+ ut_ad(extra_len >= LOG_BLOCK_HDR_SIZE);
+ extra_len-= LOG_BLOCK_HDR_SIZE;
+
+ /* total extra length for block header and trailer */
+ extra_len= ((len + extra_len) / len_per_blk) * framing_size;
+
+ const ulint margin= len + extra_len;
+
+ mysql_mutex_assert_owner(&log_sys.mutex);
+
+ const lsn_t lsn= log_sys.get_lsn();
+
+ if (UNIV_UNLIKELY(margin > log_sys.log_capacity))
+ {
+ time_t t= time(nullptr);
+
+ /* return with warning output to avoid deadlock */
+ if (!log_margin_warned || difftime(t, log_margin_warn_time) > 15)
+ {
+ log_margin_warned= true;
+ log_margin_warn_time= t;
+
+ ib::error() << "innodb_log_file_size is too small "
+ "for mini-transaction size " << len;
+ }
+ }
+ else if (UNIV_LIKELY(lsn + margin <= log_sys.last_checkpoint_lsn +
+ log_sys.log_capacity))
+ return;
+
+ log_sys.set_check_flush_or_checkpoint();
+}
+
+
+/** Open the log for log_write_low(). The log must be closed with log_close().
+@param len length of the data to be written
+@return start lsn of the log record */
+static lsn_t log_reserve_and_open(size_t len)
+{
+ for (ut_d(ulint count= 0);;)
+ {
+ mysql_mutex_assert_owner(&log_sys.mutex);
+
+ /* Calculate an upper limit for the space the string may take in
+ the log buffer */
+
+ size_t len_upper_limit= (4 * OS_FILE_LOG_BLOCK_SIZE) +
+ srv_log_write_ahead_size + (5 * len) / 4;
+
+ if (log_sys.buf_free + len_upper_limit <= srv_log_buffer_size)
+ break;
+
+ mysql_mutex_unlock(&log_sys.mutex);
+ DEBUG_SYNC_C("log_buf_size_exceeded");
+
+ /* Not enough free space, do a write of the log buffer */
+ log_sys.initiate_write(false);
+
+ srv_stats.log_waits.inc();
+
+ ut_ad(++count < 50);
+
+ mysql_mutex_lock(&log_sys.mutex);
+ }
+
+ return log_sys.get_lsn();
+}
+
+/** Append data to the log buffer. */
+static void log_write_low(const void *str, size_t size)
+{
+ mysql_mutex_assert_owner(&log_sys.mutex);
+ const ulint trailer_offset= log_sys.trailer_offset();
+
+ do
+ {
+ /* Calculate a part length */
+ size_t len= size;
+ size_t data_len= (log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE) + size;
+
+ if (data_len > trailer_offset)
+ {
+ data_len= trailer_offset;
+ len= trailer_offset - log_sys.buf_free % OS_FILE_LOG_BLOCK_SIZE;
+ }
+
+ memcpy(log_sys.buf + log_sys.buf_free, str, len);
+
+ size-= len;
+ str= static_cast<const char*>(str) + len;
+
+ byte *log_block= static_cast<byte*>(ut_align_down(log_sys.buf +
+ log_sys.buf_free,
+ OS_FILE_LOG_BLOCK_SIZE));
+
+ log_block_set_data_len(log_block, data_len);
+ lsn_t lsn= log_sys.get_lsn();
+
+ if (data_len == trailer_offset)
+ {
+ /* This block became full */
+ log_block_set_data_len(log_block, OS_FILE_LOG_BLOCK_SIZE);
+ log_block_set_checkpoint_no(log_block, log_sys.next_checkpoint_no);
+ len+= log_sys.framing_size();
+ lsn+= len;
+ /* Initialize the next block header */
+ log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, lsn);
+ }
+ else
+ lsn+= len;
+
+ log_sys.set_lsn(lsn);
+ log_sys.buf_free+= len;
+
+ ut_ad(log_sys.buf_free <= size_t{srv_log_buffer_size});
+ }
+ while (size);
+}
+
+/** Close the log at mini-transaction commit.
+@return whether buffer pool flushing is needed */
+static bool log_close(lsn_t lsn)
+{
+ mysql_mutex_assert_owner(&log_sys.mutex);
+ ut_ad(lsn == log_sys.get_lsn());
+
+ byte *log_block= static_cast<byte*>(ut_align_down(log_sys.buf +
+ log_sys.buf_free,
+ OS_FILE_LOG_BLOCK_SIZE));
+
+ if (!log_block_get_first_rec_group(log_block))
+ {
+ /* We initialized a new log block which was not written
+ full by the current mtr: the next mtr log record group
+ will start within this block at the offset data_len */
+ log_block_set_first_rec_group(log_block,
+ log_block_get_data_len(log_block));
+ }
+
+ if (log_sys.buf_free > log_sys.max_buf_free)
+ log_sys.set_check_flush_or_checkpoint();
+
+ const lsn_t checkpoint_age= lsn - log_sys.last_checkpoint_lsn;
+
+ if (UNIV_UNLIKELY(checkpoint_age >= log_sys.log_capacity))
+ {
+ time_t t= time(nullptr);
+ if (!log_close_warned || difftime(t, log_close_warn_time) > 15)
+ {
+ log_close_warned= true;
+ log_close_warn_time= t;
+
+ ib::error() << "The age of the last checkpoint is " << checkpoint_age
+ << ", which exceeds the log capacity "
+ << log_sys.log_capacity << ".";
+ }
+ }
+ else if (UNIV_LIKELY(checkpoint_age <= log_sys.max_checkpoint_age))
+ return false;
+
+ log_sys.set_check_flush_or_checkpoint();
+ return true;
+}
+
+/** Write the block contents to the REDO log */
+struct mtr_write_log
+{
+ /** Append a block to the redo log buffer.
+ @return whether the appending should continue */
+ bool operator()(const mtr_buf_t::block_t *block) const
+ {
+ log_write_low(block->begin(), block->used());
+ return true;
+ }
+};
+
/** Prepare to write the mini-transaction log to the redo log buffer.
@return number of bytes to write in finish_write() */
inline ulint mtr_t::prepare_write()
@@ -630,7 +820,7 @@ inline ulint mtr_t::prepare_write()
if (UNIV_UNLIKELY(m_log_mode != MTR_LOG_ALL)) {
ut_ad(m_log_mode == MTR_LOG_NO_REDO);
ut_ad(m_log.size() == 0);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
m_commit_lsn = log_sys.get_lsn();
return 0;
}
@@ -649,7 +839,7 @@ inline ulint mtr_t::prepare_write()
space = NULL;
}
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (fil_names_write_if_was_clean(space)) {
len = m_log.size();
@@ -668,13 +858,13 @@ inline ulint mtr_t::prepare_write()
return(len);
}
-/** Append the redo log records to the redo log buffer
-@param[in] len number of bytes to write
-@return start_lsn */
-inline lsn_t mtr_t::finish_write(ulint len)
+/** Append the redo log records to the redo log buffer.
+@param len number of bytes to write
+@return {start_lsn,flush_ahead_lsn} */
+inline std::pair<lsn_t,bool> mtr_t::finish_write(ulint len)
{
ut_ad(m_log_mode == MTR_LOG_ALL);
- ut_ad(log_mutex_own());
+ mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(m_log.size() == len);
ut_ad(len > 0);
@@ -688,18 +878,19 @@ inline lsn_t mtr_t::finish_write(ulint len)
&start_lsn);
if (m_commit_lsn) {
- return start_lsn;
+ return std::make_pair(start_lsn, false);
}
}
/* Open the database log for log_write_low */
start_lsn = log_reserve_and_open(len);
- mtr_write_log_t write_log;
+ mtr_write_log write_log;
m_log.for_each_block(write_log);
+ m_commit_lsn = log_sys.get_lsn();
+ bool flush = log_close(m_commit_lsn);
- m_commit_lsn = log_close();
- return start_lsn;
+ return std::make_pair(start_lsn, flush);
}
/** Find buffer fix count of the given block acquired by the
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index accd2417cf5..01eed0c75f6 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -51,8 +51,8 @@ Created 10/21/1995 Heikki Tuuri
#endif
#include "os0event.h"
#include "os0thread.h"
+#include "buf0dblwr.h"
-#include <vector>
#include <tpool_structs.h>
#ifdef LINUX_NATIVE_AIO
@@ -135,7 +135,6 @@ public:
static io_slots *read_slots;
static io_slots *write_slots;
-static io_slots *ibuf_slots;
/** Number of retries for partial I/O's */
constexpr ulint NUM_RETRIES_ON_PARTIAL_IO = 10;
@@ -153,9 +152,6 @@ static ulint os_innodb_umask = 0;
#endif /* _WIN32 */
-/** Flag indicating if the page_cleaner is in active state. */
-extern bool buf_page_cleaner_is_active;
-
#ifdef WITH_INNODB_DISALLOW_WRITES
#define WAIT_ALLOW_WRITES() os_event_wait(srv_allow_writes_event)
#else
@@ -1387,7 +1383,8 @@ os_file_create_func(
ut_a(type == OS_LOG_FILE
|| type == OS_DATA_FILE
- || type == OS_DATA_TEMP_FILE);
+ || type == OS_DATA_TEMP_FILE
+ || type == OS_DATA_FILE_NO_O_DIRECT);
ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
@@ -1433,7 +1430,8 @@ os_file_create_func(
/* We disable OS caching (O_DIRECT) only on data files */
if (!read_only
&& *success
- && (type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE)
+ && type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE
+ && type != OS_DATA_FILE_NO_O_DIRECT
&& (srv_file_flush_method == SRV_O_DIRECT
|| srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) {
@@ -1891,39 +1889,56 @@ os_file_status_win32(
return(true);
}
+/* Dynamically load NtFlushBuffersFileEx, used in os_file_flush_func */
+#include <winternl.h>
+typedef NTSTATUS(WINAPI* pNtFlushBuffersFileEx)(
+ HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParametersSize,
+ PIO_STATUS_BLOCK IoStatusBlock);
+
+static pNtFlushBuffersFileEx my_NtFlushBuffersFileEx
+ = (pNtFlushBuffersFileEx)GetProcAddress(GetModuleHandle("ntdll"),
+ "NtFlushBuffersFileEx");
+
/** NOTE! Use the corresponding macro os_file_flush(), not directly this
function!
Flushes the write buffers of a given file to the disk.
@param[in] file handle to a file
@return true if success */
-bool
-os_file_flush_func(
- os_file_t file)
+bool os_file_flush_func(os_file_t file)
{
- ++os_n_fsyncs;
+ ++os_n_fsyncs;
+ static bool disable_datasync;
- BOOL ret = FlushFileBuffers(file);
-
- if (ret) {
- return(true);
- }
+ if (my_NtFlushBuffersFileEx && !disable_datasync)
+ {
+ IO_STATUS_BLOCK iosb{};
+ NTSTATUS status= my_NtFlushBuffersFileEx(
+ file, FLUSH_FLAGS_FILE_DATA_SYNC_ONLY, nullptr, 0, &iosb);
+ if (!status)
+ return true;
+ /*
+ NtFlushBuffersFileEx(FLUSH_FLAGS_FILE_DATA_SYNC_ONLY) might fail
+ unless on Win10+, and maybe non-NTFS. Switch to using FlushFileBuffers().
+ */
+ disable_datasync= true;
+ }
- /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is
- actually a raw device, we choose to ignore that error if we are using
- raw disks */
+ if (FlushFileBuffers(file))
+ return true;
- if (srv_start_raw_disk_in_use && GetLastError()
- == ERROR_INVALID_FUNCTION) {
- return(true);
- }
+ /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is
+ actually a raw device, we choose to ignore that error if we are using
+ raw disks */
+ if (srv_start_raw_disk_in_use && GetLastError() == ERROR_INVALID_FUNCTION)
+ return true;
- os_file_handle_error(NULL, "flush");
+ os_file_handle_error(nullptr, "flush");
- /* It is a fatal error if a file flush does not succeed, because then
- the database can get corrupt on disk */
- ut_error;
+ /* It is a fatal error if a file flush does not succeed, because then
+ the database can get corrupt on disk */
+ ut_error;
- return(false);
+ return false;
}
/** Retrieves the last error number if an error occurs in a file io function.
@@ -3149,14 +3164,7 @@ os_file_io(
bytes_returned += n_bytes;
- if (offset > 0
- && type.is_write()
- && type.punch_hole()) {
- *err = type.punch_hole(file, offset, n);
-
- } else {
- *err = DB_SUCCESS;
- }
+ *err = type.maybe_punch_hole(offset, n);
return(original_n);
}
@@ -3167,8 +3175,7 @@ os_file_io(
bytes_returned += n_bytes;
- if (!type.is_partial_io_warning_disabled()) {
-
+ if (type.type != IORequest::READ_MAYBE_PARTIAL) {
const char* op = type.is_read()
? "read" : "written";
@@ -3186,7 +3193,7 @@ os_file_io(
*err = DB_IO_ERROR;
- if (!type.is_partial_io_warning_disabled()) {
+ if (type.type != IORequest::READ_MAYBE_PARTIAL) {
ib::warn()
<< "Retry attempts for "
<< (type.is_read() ? "reading" : "writing")
@@ -3214,7 +3221,6 @@ os_file_pwrite(
os_offset_t offset,
dberr_t* err)
{
- ut_ad(type.validate());
ut_ad(type.is_write());
++os_n_file_writes;
@@ -3248,7 +3254,6 @@ os_file_write_func(
{
dberr_t err;
- ut_ad(type.validate());
ut_ad(n > 0);
WAIT_ALLOW_WRITES();
@@ -3338,7 +3343,6 @@ os_file_read_page(
os_bytes_read_since_printout += n;
- ut_ad(type.validate());
ut_ad(n > 0);
ssize_t n_bytes = os_file_pread(type, file, buf, n, offset, &err);
@@ -3663,13 +3667,9 @@ fallback:
n_bytes = buf_size;
}
- dberr_t err;
- IORequest request(IORequest::WRITE);
-
- err = os_file_write(
- request, name, file, buf, current_size, n_bytes);
-
- if (err != DB_SUCCESS) {
+ if (os_file_write(IORequestWrite, name,
+ file, buf, current_size, n_bytes) !=
+ DB_SUCCESS) {
break;
}
@@ -3792,18 +3792,11 @@ os_file_punch_hole(
#endif /* _WIN32 */
}
-inline bool IORequest::should_punch_hole() const
-{
- return m_fil_node && m_fil_node->space->punch_hole;
-}
-
/** Free storage space associated with a section of the file.
-@param[in] fh Open file handle
-@param[in] off Starting offset (SEEK_SET)
-@param[in] len Size of the hole
+@param off byte offset from the start (SEEK_SET)
+@param len size of the hole in bytes
@return DB_SUCCESS or error code */
-dberr_t
-IORequest::punch_hole(os_file_t fh, os_offset_t off, ulint len)
+dberr_t IORequest::punch_hole(os_offset_t off, ulint len) const
{
/* In this debugging mode, we act as if punch hole is supported,
and then skip any calls to actually punch a hole here.
@@ -3812,7 +3805,7 @@ IORequest::punch_hole(os_file_t fh, os_offset_t off, ulint len)
return(DB_SUCCESS);
);
- ulint trim_len = get_trim_length(len);
+ ulint trim_len = bpage ? bpage->physical_size() - len : 0;
if (trim_len == 0) {
return(DB_SUCCESS);
@@ -3822,11 +3815,11 @@ IORequest::punch_hole(os_file_t fh, os_offset_t off, ulint len)
/* Check does file system support punching holes for this
tablespace. */
- if (!should_punch_hole()) {
+ if (!node->space->punch_hole) {
return DB_IO_NO_PUNCH_HOLE;
}
- dberr_t err = os_file_punch_hole(fh, off, trim_len);
+ dberr_t err = os_file_punch_hole(node->handle, off, trim_len);
if (err == DB_SUCCESS) {
srv_stats.page_compressed_trim_op.inc();
@@ -3834,9 +3827,7 @@ IORequest::punch_hole(os_file_t fh, os_offset_t off, ulint len)
/* If punch hole is not supported,
set space so that it is not used. */
if (err == DB_IO_NO_PUNCH_HOLE) {
- if (m_fil_node) {
- m_fil_node->space->punch_hole = false;
- }
+ node->space->punch_hole = false;
err = DB_SUCCESS;
}
}
@@ -3885,26 +3876,26 @@ os_file_get_status(
}
-extern void fil_aio_callback(os_aio_userdata_t *data);
+extern void fil_aio_callback(const IORequest &request);
static void io_callback(tpool::aiocb* cb)
{
- ut_a(cb->m_err == DB_SUCCESS);
- os_aio_userdata_t data(cb->m_userdata);
- /* Return cb back to cache*/
- if (cb->m_opcode == tpool::aio_opcode::AIO_PREAD) {
- if (read_slots->contains(cb)) {
- read_slots->release(cb);
- } else {
- ut_ad(ibuf_slots->contains(cb));
- ibuf_slots->release(cb);
- }
- } else {
- ut_ad(write_slots->contains(cb));
- write_slots->release(cb);
- }
+ ut_a(cb->m_err == DB_SUCCESS);
+ const IORequest request(*static_cast<const IORequest*>
+ (static_cast<const void*>(cb->m_userdata)));
+ /* Return cb back to cache*/
+ if (cb->m_opcode == tpool::aio_opcode::AIO_PREAD)
+ {
+ ut_ad(read_slots->contains(cb));
+ read_slots->release(cb);
+ }
+ else
+ {
+ ut_ad(write_slots->contains(cb));
+ write_slots->release(cb);
+ }
- fil_aio_callback(&data);
+ fil_aio_callback(request);
}
#ifdef LINUX_NATIVE_AIO
@@ -4041,8 +4032,7 @@ bool os_aio_init(ulint n_reader_threads, ulint n_writer_threads, ulint)
{
int max_write_events= int(n_writer_threads * OS_AIO_N_PENDING_IOS_PER_THREAD);
int max_read_events= int(n_reader_threads * OS_AIO_N_PENDING_IOS_PER_THREAD);
- int max_ibuf_events = 1 * OS_AIO_N_PENDING_IOS_PER_THREAD;
- int max_events = max_read_events + max_write_events + max_ibuf_events;
+ int max_events = max_read_events + max_write_events;
int ret;
#if LINUX_NATIVE_AIO
@@ -4061,7 +4051,6 @@ bool os_aio_init(ulint n_reader_threads, ulint n_writer_threads, ulint)
}
read_slots = new io_slots(max_read_events, (uint)n_reader_threads);
write_slots = new io_slots(max_write_events, (uint)n_writer_threads);
- ibuf_slots = new io_slots(max_ibuf_events, 1);
return true;
}
@@ -4070,15 +4059,12 @@ void os_aio_free()
srv_thread_pool->disable_aio();
delete read_slots;
delete write_slots;
- delete ibuf_slots;
read_slots= nullptr;
write_slots= nullptr;
- ibuf_slots= nullptr;
}
-/** Waits until there are no pending writes. There can
-be other, synchronous, pending writes. */
-void os_aio_wait_until_no_pending_writes()
+/** Wait until there are no pending asynchronous writes. */
+static void os_aio_wait_until_no_pending_writes_low()
{
bool notify_wait = write_slots->pending_io_count() > 0;
@@ -4091,102 +4077,90 @@ void os_aio_wait_until_no_pending_writes()
tpool::tpool_wait_end();
}
-
-/**
-NOTE! Use the corresponding macro os_aio(), not directly this function!
-Requests an asynchronous i/o operation.
-@param[in,out] type IO request context
-@param[in] mode IO mode
-@param[in] name Name of the file or path as NUL terminated
- string
-@param[in] file Open file handle
-@param[out] buf buffer where to read
-@param[in] offset file offset where to read
-@param[in] n number of bytes to read
-@param[in] read_only if true read only mode checks are enforced
-@param[in,out] m1 Message for the AIO handler, (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-@param[in,out] m2 message for the AIO handler (can be used to
- identify a completed AIO operation); ignored
- if mode is OS_AIO_SYNC
-
-@return DB_SUCCESS or error code */
-dberr_t
-os_aio_func(
- IORequest& type,
- ulint mode,
- const char* name,
- pfs_os_file_t file,
- void* buf,
- os_offset_t offset,
- ulint n,
- bool read_only,
- fil_node_t* m1,
- void* m2)
+/** Waits until there are no pending writes. There can
+be other, synchronous, pending writes. */
+void os_aio_wait_until_no_pending_writes()
{
+ os_aio_wait_until_no_pending_writes_low();
+ buf_dblwr.wait_flush_buffered_writes();
+}
+/** Request a read or write.
+@param type I/O request
+@param buf buffer
+@param offset file offset
+@param n number of bytes
+@retval DB_SUCCESS if request was queued successfully
+@retval DB_IO_ERROR on I/O error */
+dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n)
+{
ut_ad(n > 0);
ut_ad((n % OS_FILE_LOG_BLOCK_SIZE) == 0);
ut_ad((offset % OS_FILE_LOG_BLOCK_SIZE) == 0);
+ ut_ad(type.is_read() || type.is_write());
+ ut_ad(type.node);
+ ut_ad(type.node->is_open());
#ifdef WIN_ASYNC_IO
ut_ad((n & 0xFFFFFFFFUL) == n);
#endif /* WIN_ASYNC_IO */
- DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- mode = OS_AIO_SYNC; os_has_said_disk_full = FALSE;);
-
- if (mode == OS_AIO_SYNC) {
- if (type.is_read()) {
- return(os_file_read_func(type, file, buf, offset, n));
- }
-
- ut_ad(type.is_write());
-
- return(os_file_write_func(type, name, file, buf, offset, n));
+#ifdef UNIV_PFS_IO
+ PSI_file_locker_state state;
+ PSI_file_locker* locker= nullptr;
+ register_pfs_file_io_begin(&state, locker, type.node->handle, n,
+ type.is_write()
+ ? PSI_FILE_WRITE : PSI_FILE_READ,
+ __FILE__, __LINE__);
+#endif /* UNIV_PFS_IO */
+ dberr_t err = DB_SUCCESS;
+
+ if (!type.is_async()) {
+ err = type.is_read()
+ ? os_file_read_func(type, type.node->handle,
+ buf, offset, n)
+ : os_file_write_func(type, type.node->name,
+ type.node->handle,
+ buf, offset, n);
+func_exit:
+#ifdef UNIV_PFS_IO
+ register_pfs_file_io_end(locker, n);
+#endif /* UNIV_PFS_IO */
+ return err;
}
if (type.is_read()) {
- ++os_n_file_reads;
- } else if (type.is_write()) {
- ++os_n_file_writes;
+ ++os_n_file_reads;
} else {
- ut_error;
+ ++os_n_file_writes;
}
- compile_time_assert(sizeof(os_aio_userdata_t) <= tpool::MAX_AIO_USERDATA_LEN);
- os_aio_userdata_t userdata{m1,type,m2};
- io_slots* slots;
- if (type.is_read()) {
- slots = mode == OS_AIO_IBUF?ibuf_slots: read_slots;
- } else {
- slots = write_slots;
- }
+ compile_time_assert(sizeof(IORequest) <= tpool::MAX_AIO_USERDATA_LEN);
+ io_slots* slots= type.is_read() ? read_slots : write_slots;
tpool::aiocb* cb = slots->acquire();
cb->m_buffer = buf;
cb->m_callback = (tpool::callback_func)io_callback;
cb->m_group = slots->get_task_group();
- cb->m_fh = file.m_file;
+ cb->m_fh = type.node->handle.m_file;
cb->m_len = (int)n;
cb->m_offset = offset;
cb->m_opcode = type.is_read() ? tpool::aio_opcode::AIO_PREAD : tpool::aio_opcode::AIO_PWRITE;
- memcpy(cb->m_userdata, &userdata, sizeof(userdata));
+ new (cb->m_userdata) IORequest{type};
ut_a(reinterpret_cast<size_t>(cb->m_buffer) % OS_FILE_LOG_BLOCK_SIZE
== 0);
ut_a(cb->m_len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(cb->m_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- if (!srv_thread_pool->submit_io(cb))
- return DB_SUCCESS;
-
- slots->release(cb);
-
- os_file_handle_error(name, type.is_read() ? "aio read" : "aio write");
+ if (srv_thread_pool->submit_io(cb)) {
+ slots->release(cb);
+ os_file_handle_error(type.node->name, type.is_read()
+ ? "aio read" : "aio write");
+ err = DB_IO_ERROR;
+ }
- return(DB_IO_ERROR);
+ goto func_exit;
}
/** Prints info of the aio arrays.
@@ -4220,7 +4194,7 @@ os_aio_print(FILE* file)
ULINTPF " OS file writes, "
ULINTPF " OS fsyncs\n",
log_sys.get_pending_flushes(),
- fil_n_pending_tablespace_flushes,
+ ulint{fil_n_pending_tablespace_flushes},
os_n_file_reads,
os_n_file_writes,
os_n_fsyncs);
@@ -4470,12 +4444,11 @@ void fil_node_t::find_metadata(os_file_t file
}
/** Read the first page of a data file.
-@param[in] first whether this is the very first read
@return whether the page was found valid */
-bool fil_node_t::read_page0(bool first)
+bool fil_node_t::read_page0()
{
ut_ad(mutex_own(&fil_system.mutex));
- const ulint psize = space->physical_size();
+ const unsigned psize = space->physical_size();
#ifndef _WIN32
struct stat statbuf;
if (fstat(handle, &statbuf)) {
@@ -4487,7 +4460,7 @@ bool fil_node_t::read_page0(bool first)
os_offset_t size_bytes = os_file_get_size(handle);
ut_a(size_bytes != (os_offset_t) -1);
#endif
- const ulint min_size = FIL_IBD_FILE_INITIAL_SIZE * psize;
+ const uint32_t min_size = FIL_IBD_FILE_INITIAL_SIZE * psize;
if (size_bytes < min_size) {
ib::error() << "The size of the file " << name
@@ -4511,10 +4484,10 @@ corrupted:
? ULINT_UNDEFINED
: mach_read_from_4(FIL_PAGE_SPACE_ID + page);
ulint flags = fsp_header_get_flags(page);
- const ulint size = fsp_header_get_field(page, FSP_SIZE);
- const ulint free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT);
- const ulint free_len = flst_get_len(FSP_HEADER_OFFSET + FSP_FREE
- + page);
+ const uint32_t size = fsp_header_get_field(page, FSP_SIZE);
+ const uint32_t free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT);
+ const uint32_t free_len = flst_get_len(FSP_HEADER_OFFSET + FSP_FREE
+ + page);
if (!fil_space_t::is_valid_flags(flags, space->id)) {
ulint cflags = fsp_flags_convert_from_101(flags);
if (cflags == ULINT_UNDEFINED) {
@@ -4554,41 +4527,26 @@ invalid:
return false;
}
- if (first) {
- ut_ad(space->id != TRX_SYS_SPACE);
#ifdef UNIV_LINUX
- find_metadata(handle, &statbuf);
+ find_metadata(handle, &statbuf);
#else
- find_metadata();
+ find_metadata();
#endif
+ /* Truncate the size to a multiple of extent size. */
+ ulint mask = psize * FSP_EXTENT_SIZE - 1;
- /* Truncate the size to a multiple of extent size. */
- ulint mask = psize * FSP_EXTENT_SIZE - 1;
-
- if (size_bytes <= mask) {
- /* .ibd files start smaller than an
- extent size. Do not truncate valid data. */
- } else {
- size_bytes &= ~os_offset_t(mask);
- }
-
- space->flags = (space->flags & FSP_FLAGS_MEM_MASK) | flags;
-
- space->punch_hole = space->is_compressed();
- this->size = ulint(size_bytes / psize);
- space->committed_size = space->size += this->size;
- } else if (space->id != TRX_SYS_SPACE || space->size_in_header) {
- /* If this is not the first-time open, do nothing.
- For the system tablespace, we always get invoked as
- first=false, so we detect the true first-time-open based
- on size_in_header and proceed to initialize the data. */
- return true;
+ if (size_bytes <= mask) {
+ /* .ibd files start smaller than an
+ extent size. Do not truncate valid data. */
} else {
- /* Initialize the size of predefined tablespaces
- to FSP_SIZE. */
- space->committed_size = size;
+ size_bytes &= ~os_offset_t(mask);
}
+ space->flags = (space->flags & FSP_FLAGS_MEM_MASK) | flags;
+
+ space->punch_hole = space->is_compressed();
+ this->size = uint32_t(size_bytes / psize);
+ space->set_sizes(this->size);
ut_ad(space->free_limit == 0 || space->free_limit == free_limit);
ut_ad(space->free_len == 0 || space->free_len == free_len);
space->size_in_header = size;
diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc
index bb5da7df7c4..47270c05acf 100644
--- a/storage/innobase/os/os0thread.cc
+++ b/storage/innobase/os/os0thread.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
@@ -27,9 +27,6 @@ Created 9/8/1995 Heikki Tuuri
#include "univ.i"
#include "srv0srv.h"
-/** Number of threads active. */
-Atomic_counter<ulint> os_thread_count;
-
/***************************************************************//**
Compares two thread ids for equality.
@return TRUE if equal */
@@ -89,15 +86,7 @@ NOTE: We count the number of threads in os_thread_exit(). A created
thread should always use that to exit so thatthe thread count will be
decremented.
We do not return an error code because if there is one, we crash here. */
-os_thread_t
-os_thread_create_func(
-/*==================*/
- os_thread_func_t func, /*!< in: pointer to function
- from which to start */
- void* arg, /*!< in: argument to start
- function */
- os_thread_id_t* thread_id) /*!< out: id of the created
- thread, or NULL */
+os_thread_t os_thread_create(os_thread_func_t func, void *arg)
{
os_thread_id_t new_thread_id;
@@ -118,8 +107,6 @@ os_thread_create_func(
CloseHandle(handle);
- os_thread_count++;
-
return((os_thread_t)new_thread_id);
#else /* _WIN32 else */
@@ -133,8 +120,6 @@ os_thread_create_func(
abort();
}
- os_thread_count++;
-
ret = pthread_create(&new_thread_id, &attr, func, arg);
ut_a(ret == 0);
@@ -143,41 +128,11 @@ os_thread_create_func(
#endif /* not _WIN32 */
- ut_a(os_thread_count <= srv_max_n_threads);
-
- /* Return the thread_id if the caller requests it. */
- if (thread_id != NULL) {
- *thread_id = new_thread_id;
- }
return((os_thread_t)new_thread_id);
}
-/** Waits until the specified thread completes and joins it.
-Its return value is ignored.
-@param[in,out] thread thread to join */
-void
-os_thread_join(
- os_thread_id_t thread)
-{
-#ifdef _WIN32
- /* Do nothing. */
-#else
-#ifdef UNIV_DEBUG
- const int ret =
-#endif /* UNIV_DEBUG */
- pthread_join(thread, NULL);
-
- /* Waiting on already-quit threads is allowed. */
- ut_ad(ret == 0 || ret == ESRCH);
-#endif /* _WIN32 */
-}
-
-/** Exits the current thread.
-@param[in] detach if true, the thread will be detached right before
-exiting. If false, another thread is responsible for joining this thread */
-ATTRIBUTE_NORETURN
-void
-os_thread_exit(bool detach)
+/** Detach and terminate the current thread. */
+ATTRIBUTE_NORETURN void os_thread_exit()
{
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Thread exits, id "
@@ -188,14 +143,10 @@ os_thread_exit(bool detach)
pfs_delete_thread();
#endif
- os_thread_count--;
-
#ifdef _WIN32
ExitThread(0);
#else
- if (detach) {
- pthread_detach(pthread_self());
- }
+ pthread_detach(pthread_self());
pthread_exit(NULL);
#endif
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 2ec0a06709e..8376fbb4ba6 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -528,7 +528,7 @@ protected:
/** Check if the page is marked as free in the extent descriptor.
@param page_no page number to check in the extent descriptor.
@return true if the page is marked as free */
- bool is_free(ulint page_no) const UNIV_NOTHROW
+ bool is_free(uint32_t page_no) const UNIV_NOTHROW
{
ut_a(xdes_calc_descriptor_page(get_zip_size(), page_no)
== m_xdes_page_no);
@@ -3423,11 +3423,9 @@ fil_iterate(
? iter.crypt_io_buffer : io_buffer;
byte* const writeptr = readptr;
- IORequest read_request(IORequest::READ);
- read_request.disable_partial_io_warnings();
-
err = os_file_read_no_error_handling(
- read_request, iter.file, readptr, offset, n_bytes, 0);
+ IORequestReadPartial,
+ iter.file, readptr, offset, n_bytes, 0);
if (err != DB_SUCCESS) {
ib::error() << iter.filepath
<< ": os_file_read() failed";
@@ -3438,7 +3436,7 @@ fil_iterate(
os_offset_t page_off = offset;
ulint n_pages_read = n_bytes / size;
/* This block is not attached to buf_pool */
- block->page.id_.set_page_no(ulint(page_off / size));
+ block->page.id_.set_page_no(uint32_t(page_off / size));
for (ulint i = 0; i < n_pages_read;
++block->page.id_,
@@ -3665,9 +3663,7 @@ not_encrypted:
/* A page was updated in the set, write back to disk. */
if (updated) {
- IORequest write_request(IORequest::WRITE);
-
- err = os_file_write(write_request,
+ err = os_file_write(IORequestWrite,
iter.filepath, iter.file,
writeptr, offset, n_bytes);
@@ -3760,11 +3756,8 @@ fil_tablespace_iterate(
/* Read the first page and determine the page and zip size. */
- IORequest request(IORequest::READ);
- request.disable_partial_io_warnings();
-
- err = os_file_read_no_error_handling(request, file, page, 0,
- srv_page_size, 0);
+ err = os_file_read_no_error_handling(IORequestReadPartial,
+ file, page, 0, srv_page_size, 0);
if (err == DB_SUCCESS) {
err = callback.init(file_size, block);
@@ -3861,7 +3854,6 @@ row_import_for_mysql(
trx_t* trx;
ib_uint64_t autoinc = 0;
char* filepath = NULL;
- ulint space_flags MY_ATTRIBUTE((unused));
/* The caller assured that this is not read_only_mode and that no
temorary tablespace is being imported. */
@@ -3980,9 +3972,6 @@ row_import_for_mysql(
err = cfg.set_root_by_heuristic();
}
}
-
- space_flags = fetchIndexRootPages.get_space_flags();
-
} else {
rw_lock_s_unlock(&dict_sys.latch);
}
@@ -4175,7 +4164,7 @@ row_import_for_mysql(
/* Ensure that all pages dirtied during the IMPORT make it to disk.
The only dirty pages generated should be from the pessimistic purge
of delete marked records that couldn't be purged in Phase I. */
- buf_LRU_flush_or_remove_pages(prebuilt->table->space_id, true);
+ while (buf_flush_dirty_pages(prebuilt->table->space_id));
ib::info() << "Phase IV - Flush complete";
prebuilt->table->space->set_imported();
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 75a7238c1df..5e41d037b6c 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -460,7 +460,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- bool affects_fulltext = false;
+ bool affects_fulltext = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -583,17 +583,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),
- col->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -1223,8 +1212,6 @@ row_ins_foreign_check_on_constraint(
MEM_UNDEFINED(update->fields,
update->n_fields * sizeof *update->fields);
- bool affects_fulltext = false;
-
for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
ulint col_no = dict_index_get_nth_col_no(
@@ -1241,19 +1228,9 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (!affects_fulltext
- && table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col(index, i)->ind,
- dict_index_get_nth_col(index, i)
- ->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- }
}
- if (affects_fulltext) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
@@ -1267,24 +1244,10 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
}
- } else if (table->fts && cascade->is_delete == PLAIN_DELETE) {
+ } else if (table->fts && cascade->is_delete == PLAIN_DELETE
+ && foreign->affects_fulltext()) {
/* DICT_FOREIGN_ON_DELETE_CASCADE case */
- bool affects_fulltext = false;
-
- for (ulint i = 0; i < foreign->n_fields; i++) {
- if (dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col(index, i)->ind,
- dict_index_get_nth_col(index, i)->is_virtual())
- != ULINT_UNDEFINED) {
- affects_fulltext = true;
- break;
- }
- }
-
- if (affects_fulltext) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
@@ -1907,8 +1870,14 @@ bool row_ins_foreign_index_entry(dict_foreign_t *foreign,
{
for (ulint j= 0; j < index->n_fields; j++)
{
- const char *col_name= dict_table_get_col_name(
- index->table, dict_index_get_nth_col_no(index, j));
+ const dict_col_t *col= dict_index_get_nth_col(index, j);
+
+ /* A clustered index may contain instantly dropped columns,
+ which must be skipped. */
+ if (col->is_dropped())
+ continue;
+
+ const char *col_name= dict_table_get_col_name(index->table, col->ind);
if (0 == innobase_strcasecmp(col_name, foreign->foreign_col_names[i]))
{
dfield_copy(&ref_entry->fields[i], &entry->fields[j]);
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 4db1b7cfa7f..02429aac23b 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -410,7 +410,6 @@ row_log_online_op(
const os_offset_t byte_offset
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
- IORequest request(IORequest::WRITE);
byte* buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
@@ -448,7 +447,7 @@ row_log_online_op(
log->tail.blocks++;
if (os_file_write(
- request,
+ IORequestWrite,
"(modification log)",
log->fd,
buf, byte_offset, srv_sort_buf_size)
@@ -549,7 +548,6 @@ row_log_table_close_func(
const os_offset_t byte_offset
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
- IORequest request(IORequest::WRITE);
byte* buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
@@ -587,7 +585,7 @@ row_log_table_close_func(
log->tail.blocks++;
if (os_file_write(
- request,
+ IORequestWrite,
"(modification log)",
log->fd,
buf, byte_offset, srv_sort_buf_size)
@@ -2874,11 +2872,10 @@ all_done:
goto func_exit;
}
- IORequest request(IORequest::READ);
byte* buf = index->online_log->head.block;
if (os_file_read_no_error_handling(
- request, index->online_log->fd,
+ IORequestRead, index->online_log->fd,
buf, ofs, srv_sort_buf_size, 0) != DB_SUCCESS) {
ib::error()
<< "Unable to read temporary file"
@@ -3767,8 +3764,6 @@ all_done:
os_offset_t ofs = static_cast<os_offset_t>(
index->online_log->head.blocks)
* srv_sort_buf_size;
- IORequest request(IORequest::READ);
-
ut_ad(has_index_lock);
has_index_lock = false;
rw_lock_x_unlock(dict_index_get_lock(index));
@@ -3783,7 +3778,7 @@ all_done:
byte* buf = index->online_log->head.block;
if (os_file_read_no_error_handling(
- request, index->online_log->fd,
+ IORequestRead, index->online_log->fd,
buf, ofs, srv_sort_buf_size, 0) != DB_SUCCESS) {
ib::error()
<< "Unable to read temporary file"
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 37814b70188..558bf6d5a07 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1080,9 +1080,8 @@ row_merge_read(
DBUG_LOG("ib_merge_sort", "fd=" << fd << " ofs=" << ofs);
DBUG_EXECUTE_IF("row_merge_read_failure", DBUG_RETURN(FALSE););
- IORequest request(IORequest::READ);
const bool success = DB_SUCCESS == os_file_read_no_error_handling(
- request, fd, buf, ofs, srv_sort_buf_size, 0);
+ IORequestRead, fd, buf, ofs, srv_sort_buf_size, 0);
/* If encryption is enabled decrypt buffer */
if (success && log_tmp_is_encrypted()) {
@@ -1144,9 +1143,8 @@ row_merge_write(
out_buf = crypt_buf;
}
- IORequest request(IORequest::WRITE);
const bool success = DB_SUCCESS == os_file_write(
- request, "(merge)", fd, out_buf, ofs, buf_len);
+ IORequestWrite, "(merge)", fd, out_buf, ofs, buf_len);
#ifdef POSIX_FADV_DONTNEED
/* The block will be needed on the next merge pass,
@@ -2001,18 +1999,14 @@ end_of_index:
goto write_buffers;
}
} else {
- ulint next_page_no;
- buf_block_t* block;
-
- next_page_no = btr_page_get_next(
+ uint32_t next_page_no = btr_page_get_next(
page_cur_get_page(cur));
if (next_page_no == FIL_NULL) {
goto end_of_index;
}
- block = page_cur_get_block(cur);
- block = btr_block_get(
+ buf_block_t* block = btr_block_get(
*clust_index, next_page_no,
RW_S_LATCH, false, &mtr);
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 00c2c41c1d0..33aa578873f 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1522,7 +1522,7 @@ error_exit:
srv_stats.n_rows_inserted.inc(size_t(trx->id));
}
- /* Not protected by dict_table_stats_lock() for performance
+ /* Not protected by dict_sys.mutex for performance
reasons, we would rather get garbage in stat_n_rows (which is
just an estimate anyway) than protecting the following code
with a latch. */
@@ -1892,7 +1892,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
ut_ad(is_delete == (node->is_delete == PLAIN_DELETE));
if (is_delete) {
- /* Not protected by dict_table_stats_lock() for performance
+ /* Not protected by dict_sys.mutex for performance
reasons, we would rather get garbage in stat_n_rows (which is
just an estimate anyway) than protecting the following code
with a latch. */
@@ -2234,8 +2234,7 @@ row_update_cascade_for_mysql(
bool stats;
if (node->is_delete == PLAIN_DELETE) {
- /* Not protected by
- dict_table_stats_lock() for
+ /* Not protected by dict_sys.mutex for
performance reasons, we would rather
get garbage in stat_n_rows (which is
just an estimate anyway) than
@@ -3391,8 +3390,7 @@ row_drop_table_for_mysql(
dict_stats_recalc_pool_del(table);
dict_stats_defrag_pool_del(table, NULL);
if (btr_defragment_active) {
- /* During fts_drop_orphaned_tables() in
- recv_recovery_rollback_active() the
+ /* During fts_drop_orphaned_tables() the
btr_defragment_mutex has not yet been
initialized by btr_defragment_init(). */
btr_defragment_remove_table(table);
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index ff50e4f1510..0bdf52dfd56 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -525,17 +525,27 @@ row_quiesce_table_start(
}
for (ulint count = 0;
- ibuf_merge_space(table->space_id) != 0
- && !trx_is_interrupted(trx);
+ ibuf_merge_space(table->space_id);
++count) {
+ if (trx_is_interrupted(trx)) {
+ goto aborted;
+ }
if (!(count % 20)) {
ib::info() << "Merging change buffer entries for "
<< table->name;
}
}
+ while (buf_flush_dirty_pages(table->space_id)) {
+ if (trx_is_interrupted(trx)) {
+ goto aborted;
+ }
+ }
+
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(table->space_id, true);
+ /* Ensure that all asynchronous IO is completed. */
+ os_aio_wait_until_no_pending_writes();
+ table->space->flush();
if (row_quiesce_write_cfg(table, trx->mysql_thd)
!= DB_SUCCESS) {
@@ -546,6 +556,7 @@ row_quiesce_table_start(
<< " flushed to disk";
}
} else {
+aborted:
ib::warn() << "Quiesce aborted!";
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 239544c453e..d7a0490db3d 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -121,7 +121,7 @@ row_sel_sec_rec_is_for_blob(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)) {
/* The externally stored field was not written yet.
This record should only be seen by
- recv_recovery_rollback_active() or any
+ trx_rollback_recovered() or any
TRX_ISO_READ_UNCOMMITTED transactions. */
return(FALSE);
}
@@ -528,7 +528,7 @@ row_sel_fetch_columns(
externally stored field was not
written yet. This record
should only be seen by
- recv_recovery_rollback_active() or any
+ trx_rollback_recovered() or any
TRX_ISO_READ_UNCOMMITTED
transactions. The InnoDB SQL parser
(the sole caller of this function)
@@ -1109,7 +1109,7 @@ re_scan:
/* MDEV-14059 FIXME: why re-latch the block?
pcur is already positioned on it! */
- ulint page_no = page_get_page_no(
+ uint32_t page_no = page_get_page_no(
btr_pcur_get_page(pcur));
cur_block = buf_page_get_gen(
@@ -2891,7 +2891,7 @@ row_sel_store_mysql_field(
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
yet. This record should only be seen by
- recv_recovery_rollback_active() or any
+ trx_rollback_recovered() or any
TRX_ISO_READ_UNCOMMITTED transactions. */
if (heap != prebuilt->blob_heap) {
@@ -3906,7 +3906,7 @@ exhausted:
/*********************************************************************//**
Check a pushed-down index condition.
-@return CHECK_NEG, CHECK_POS, or CHECK_OUT_OF_RANGE */
+@return CHECK_ABORTED_BY_USER, CHECK_NEG, CHECK_POS, or CHECK_OUT_OF_RANGE */
static
check_result_t
row_search_idx_cond_check(
@@ -3992,7 +3992,7 @@ row_search_idx_cond_check(
case CHECK_POS:
break;
default:
- ut_error;
+ return(result);
}
}
/* Convert the remaining fields to MySQL format.
@@ -4453,15 +4453,21 @@ early_not_found:
switch (row_search_idx_cond_check(
buf, prebuilt,
rec, offsets)) {
+ case CHECK_ABORTED_BY_USER:
+ goto aborted;
case CHECK_NEG:
case CHECK_OUT_OF_RANGE:
- case CHECK_ABORTED_BY_USER:
case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto shortcut_done;
case CHECK_POS:
goto shortcut_done;
}
+
+ ut_ad("incorrect code" == 0);
+aborted:
+ err = DB_INTERRUPTED;
+ goto shortcut_done;
}
if (!row_sel_store_mysql_rec(
@@ -4495,6 +4501,9 @@ early_not_found:
trx->op_info = "";
ut_ad(!sync_check_iterate(sync_check()));
ut_ad(!did_semi_consistent_read);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
DBUG_RETURN(err);
case SEL_RETRY:
@@ -5191,9 +5200,11 @@ no_gap_lock:
buf, prebuilt, rec, offsets)) {
case CHECK_NEG:
goto next_rec;
- case CHECK_OUT_OF_RANGE:
case CHECK_ABORTED_BY_USER:
- case CHECK_ERROR:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case CHECK_OUT_OF_RANGE:
+ case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
case CHECK_POS:
@@ -5251,8 +5262,10 @@ locks_ok_del_marked:
row_unlock_for_mysql(prebuilt, TRUE);
}
goto next_rec;
- case CHECK_OUT_OF_RANGE:
case CHECK_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case CHECK_OUT_OF_RANGE:
case CHECK_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
@@ -5752,7 +5765,7 @@ normal_return:
func_exit:
trx->op_info = "";
- if (heap != NULL) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 68856d47b5e..114d83c8564 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -88,7 +88,8 @@ row_undo_ins_remove_clust_rec(
online = dict_index_is_online_ddl(index);
if (online) {
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
- ut_ad(!node->trx->dict_operation_lock_mode);
+ ut_ad(node->trx->dict_operation_lock_mode
+ != RW_X_LATCH);
ut_ad(node->table->id != DICT_INDEXES_ID);
ut_ad(node->table->id != DICT_COLUMNS_ID);
mtr_s_lock_index(index, &mtr);
@@ -400,7 +401,7 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked)
goto close_table;
}
- if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) {
+ if (UNIV_UNLIKELY(!node->table->is_accessible())) {
close_table:
/* Normally, tables should not disappear or become
unaccessible during ROLLBACK, because they should be
@@ -529,9 +530,6 @@ row_undo_ins(
return DB_SUCCESS;
}
- ut_ad(node->table->is_temporary()
- || lock_table_has_locks(node->table));
-
/* Iterate over all the indexes and undo the insert.*/
node->index = dict_table_get_first_index(node->table);
@@ -569,7 +567,7 @@ row_undo_ins(
}
if (err == DB_SUCCESS && node->table->stat_initialized) {
- /* Not protected by dict_table_stats_lock() for
+ /* Not protected by dict_sys.mutex for
performance reasons, we would rather get garbage
in stat_n_rows (which is just an estimate anyway)
than protecting the following code with a latch. */
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index d32c6cd2510..f710f54d0c1 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -244,7 +244,10 @@ row_undo_mod_clust(
bool online;
ut_ad(thr_get_trx(thr) == node->trx);
+ ut_ad(node->trx->dict_operation_lock_mode);
ut_ad(node->trx->in_rollback);
+ ut_ad(rw_lock_own_flagged(&dict_sys.latch,
+ RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
log_free_check();
pcur = &node->pcur;
@@ -261,7 +264,7 @@ row_undo_mod_clust(
online = dict_index_is_online_ddl(index);
if (online) {
- ut_ad(!node->trx->dict_operation_lock_mode);
+ ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH);
mtr_s_lock_index(index, &mtr);
}
@@ -300,7 +303,17 @@ row_undo_mod_clust(
ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
}
- if (err == DB_SUCCESS && online && dict_index_is_online_ddl(index)) {
+ /* Online rebuild cannot be initiated while we are holding
+ dict_sys.latch and index->lock. (It can be aborted.) */
+ ut_ad(online || !dict_index_is_online_ddl(index));
+
+ if (err == DB_SUCCESS && online) {
+
+ ut_ad(rw_lock_own_flagged(
+ &index->lock,
+ RW_LOCK_FLAG_S | RW_LOCK_FLAG_X
+ | RW_LOCK_FLAG_SX));
+
switch (node->rec_type) {
case TRX_UNDO_DEL_MARK_REC:
row_log_table_insert(
@@ -875,6 +888,37 @@ func_exit_no_pcur:
}
/***********************************************************//**
+Flags a secondary index corrupted. */
+static MY_ATTRIBUTE((nonnull))
+void
+row_undo_mod_sec_flag_corrupted(
+/*============================*/
+ trx_t* trx, /*!< in/out: transaction */
+ dict_index_t* index) /*!< in: secondary index */
+{
+ ut_ad(!dict_index_is_clust(index));
+
+ switch (trx->dict_operation_lock_mode) {
+ case RW_S_LATCH:
+ /* Because row_undo() is holding an S-latch
+ on the data dictionary during normal rollback,
+ we can only mark the index corrupted in the
+ data dictionary cache. TODO: fix this somehow.*/
+ mutex_enter(&dict_sys.mutex);
+ dict_set_corrupted_index_cache_only(index);
+ mutex_exit(&dict_sys.mutex);
+ break;
+ default:
+ ut_ad(0);
+ /* fall through */
+ case RW_X_LATCH:
+ /* This should be the rollback of a data dictionary
+ transaction. */
+ dict_set_corrupted(index, trx, "rollback");
+ }
+}
+
+/***********************************************************//**
Undoes a modify in secondary indexes when undo record type is UPD_DEL.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
@@ -987,7 +1031,8 @@ row_undo_mod_del_mark_sec(
}
if (err == DB_DUPLICATE_KEY) {
- index->type |= DICT_CORRUPT;
+ row_undo_mod_sec_flag_corrupted(
+ thr_get_trx(thr), index);
err = DB_SUCCESS;
/* Do not return any error to the caller. The
duplicate will be reported by ALTER TABLE or
@@ -1132,7 +1177,8 @@ row_undo_mod_upd_exist_sec(
}
if (err == DB_DUPLICATE_KEY) {
- index->type |= DICT_CORRUPT;
+ row_undo_mod_sec_flag_corrupted(
+ thr_get_trx(thr), index);
err = DB_SUCCESS;
} else if (err != DB_SUCCESS) {
break;
@@ -1189,7 +1235,7 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked)
ut_ad(!node->table->skip_alter_undo);
- if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) {
+ if (UNIV_UNLIKELY(!node->table->is_accessible())) {
close_table:
/* Normally, tables should not disappear or become
unaccessible during ROLLBACK, because they should be
@@ -1295,8 +1341,6 @@ row_undo_mod(
return DB_SUCCESS;
}
- ut_ad(node->table->is_temporary()
- || lock_table_has_locks(node->table));
node->index = dict_table_get_first_index(node->table);
ut_ad(dict_index_is_clust(node->index));
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 2fe1135b894..375de331255 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -418,8 +418,7 @@ row_undo(
for online operation. (A table lock would only be acquired
when committing the ALTER TABLE operation.) */
trx_t* trx = node->trx;
- const bool locked_data_dict = UNIV_UNLIKELY(trx->is_recovered)
- && !trx->dict_operation_lock_mode;
+ const bool locked_data_dict = !trx->dict_operation_lock_mode;
if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_freeze_data_dictionary(trx);
@@ -441,7 +440,8 @@ row_undo(
err = DB_CORRUPTION;
}
- if (UNIV_UNLIKELY(locked_data_dict)) {
+ if (locked_data_dict) {
+
row_mysql_unfreeze_data_dictionary(trx);
}
@@ -466,13 +466,7 @@ row_undo_step(
{
dberr_t err;
undo_node_t* node;
- trx_t* trx;
-
- ut_ad(thr);
-
- srv_inc_activity_count();
-
- trx = thr_get_trx(thr);
+ trx_t* trx = thr_get_trx(thr);
node = static_cast<undo_node_t*>(thr->run_node);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index fa3fad5fe26..aee20477ac0 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1539,7 +1539,7 @@ row_upd_changes_ord_field_binary_func(
/* The externally stored field
was not written yet. This
record should only be seen by
- recv_recovery_rollback_active(),
+ trx_rollback_recovered()
when the server had crashed before
storing the field. */
ut_ad(thr->graph->trx->is_recovered);
diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc
index ef16c453657..174355f992a 100644
--- a/storage/innobase/srv/srv0mon.cc
+++ b/storage/innobase/srv/srv0mon.cc
@@ -381,56 +381,16 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_FLUSH_N_TO_FLUSH_BY_AGE},
- {"buffer_flush_adaptive_avg_time_slot", "buffer",
- "Avg time (ms) spent for adaptive flushing recently per slot.",
+ {"buffer_flush_adaptive_avg_time", "buffer",
+ "Avg time (ms) spent for adaptive flushing recently.",
MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_FLUSH_ADAPTIVE_AVG_TIME_SLOT},
-
- {"buffer_LRU_batch_flush_avg_time_slot", "buffer",
- "Avg time (ms) spent for LRU batch flushing recently per slot.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_FLUSH_AVG_TIME_SLOT},
-
- {"buffer_flush_adaptive_avg_time_thread", "buffer",
- "Avg time (ms) spent for adaptive flushing recently per thread.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_FLUSH_ADAPTIVE_AVG_TIME_THREAD},
-
- {"buffer_LRU_batch_flush_avg_time_thread", "buffer",
- "Avg time (ms) spent for LRU batch flushing recently per thread.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_FLUSH_AVG_TIME_THREAD},
-
- {"buffer_flush_adaptive_avg_time_est", "buffer",
- "Estimated time (ms) spent for adaptive flushing recently.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_FLUSH_ADAPTIVE_AVG_TIME_EST},
-
- {"buffer_LRU_batch_flush_avg_time_est", "buffer",
- "Estimated time (ms) spent for LRU batch flushing recently.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_FLUSH_AVG_TIME_EST},
-
- {"buffer_flush_avg_time", "buffer",
- "Avg time (ms) spent for flushing recently.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_FLUSH_AVG_TIME},
+ MONITOR_DEFAULT_START, MONITOR_FLUSH_ADAPTIVE_AVG_TIME},
{"buffer_flush_adaptive_avg_pass", "buffer",
"Number of adaptive flushes passed during the recent Avg period.",
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_FLUSH_ADAPTIVE_AVG_PASS},
- {"buffer_LRU_batch_flush_avg_pass", "buffer",
- "Number of LRU batch flushes passed during the recent Avg period.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_FLUSH_AVG_PASS},
-
- {"buffer_flush_avg_pass", "buffer",
- "Number of flushes passed during the recent Avg period.",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_FLUSH_AVG_PASS},
-
{"buffer_LRU_get_free_loops", "buffer",
"Total loops in LRU get free.",
MONITOR_NONE,
@@ -562,23 +522,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_SET_MEMBER, MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
MONITOR_LRU_BATCH_EVICT_PAGES},
- /* Cumulative counter for single page LRU scans */
- {"buffer_LRU_single_flush_scanned", "buffer",
- "Total pages scanned as part of single page LRU flush",
- MONITOR_SET_OWNER,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_NUM_CALL,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED},
-
- {"buffer_LRU_single_flush_num_scan", "buffer",
- "Number of times single page LRU flush is called",
- MONITOR_SET_MEMBER, MONITOR_LRU_SINGLE_FLUSH_SCANNED,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_NUM_CALL},
-
- {"buffer_LRU_single_flush_scanned_per_call", "buffer",
- "Page scanned per single LRU flush",
- MONITOR_SET_MEMBER, MONITOR_LRU_SINGLE_FLUSH_SCANNED,
- MONITOR_LRU_SINGLE_FLUSH_SCANNED_PER_CALL},
-
{"buffer_LRU_single_flush_failure_count", "Buffer",
"Number of times attempt to flush a single page from LRU failed",
MONITOR_NONE,
@@ -905,12 +848,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT),
MONITOR_DEFAULT_START, MONITOR_OVLD_MAX_AGE_ASYNC},
- {"log_max_modified_age_sync", "recovery",
- "Maximum LSN difference; when exceeded, start synchronous preflush",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT),
- MONITOR_DEFAULT_START, MONITOR_OVLD_MAX_AGE_SYNC},
-
{"log_pending_log_flushes", "recovery", "Pending log flushes",
static_cast<monitor_type_t>(
MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT),
@@ -1209,11 +1146,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_SRV_DICT_LRU_EVICT_COUNT_IDLE},
- {"innodb_checkpoint_usec", "server",
- "Time (in microseconds) spent by master thread to do checkpoint",
- MONITOR_NONE,
- MONITOR_DEFAULT_START, MONITOR_SRV_CHECKPOINT_MICROSECOND},
-
{"innodb_dblwr_writes", "server",
"Number of doublewrite operations that have been performed"
" (innodb_dblwr_writes)",
@@ -1468,7 +1400,8 @@ srv_mon_set_module_control(
ibool set_current_module = FALSE;
ut_a(module_id <= NUM_MONITOR);
- ut_a(UT_ARR_SIZE(innodb_counter_info) == NUM_MONITOR);
+ compile_time_assert(array_elements(innodb_counter_info)
+ == NUM_MONITOR);
/* The module_id must be an ID of MONITOR_MODULE type */
ut_a(innodb_counter_info[module_id].monitor_type & MONITOR_MODULE);
@@ -1972,27 +1905,29 @@ srv_mon_process_existing_counter(
break;
case MONITOR_PENDING_CHECKPOINT_WRITE:
- mutex_enter(&log_sys.mutex);
+ mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(
log_sys.n_pending_checkpoint_writes);
- mutex_exit(&log_sys.mutex);
+ mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_LOG_IO:
- mutex_enter(&log_sys.mutex);
+ mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(log_sys.n_log_ios);
- mutex_exit(&log_sys.mutex);
+ mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_LSN_CHECKPOINT_AGE:
- mutex_enter(&log_sys.mutex);
+ mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(log_sys.get_lsn()
- log_sys.last_checkpoint_lsn);
- mutex_exit(&log_sys.mutex);
+ mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_OVLD_BUF_OLDEST_LSN:
- value = (mon_type_t) buf_pool.get_oldest_modification();
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ value = (mon_type_t) buf_pool.get_oldest_modification(0);
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
break;
case MONITOR_OVLD_LSN_CHECKPOINT:
@@ -2003,10 +1938,6 @@ srv_mon_process_existing_counter(
value = log_sys.max_modified_age_async;
break;
- case MONITOR_OVLD_MAX_AGE_SYNC:
- value = log_sys.max_modified_age_sync;
- break;
-
#ifdef BTR_CUR_HASH_ADAPT
case MONITOR_OVLD_ADAPTIVE_HASH_SEARCH:
value = btr_cur_n_sea;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 14ed15a81c9..554e2043ad1 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -342,11 +342,6 @@ my_bool srv_stats_sample_traditional;
my_bool srv_use_doublewrite_buf;
-/** innodb_doublewrite_batch_size (a debug parameter) specifies the
-number of pages to use in LRU and flush_list batch flushing.
-The rest of the doublewrite buffer is used for single-page flushing. */
-ulong srv_doublewrite_batch_size = 120;
-
/** innodb_sync_spin_loops */
ulong srv_n_spin_wait_rounds;
/** innodb_spin_wait_delay */
@@ -459,16 +454,6 @@ UNIV_INTERN uint srv_simulate_comp_failures;
/** Buffer pool dump status frequence in percentages */
UNIV_INTERN ulong srv_buf_dump_status_frequency;
-/** Acquire the system_mutex. */
-#define srv_sys_mutex_enter() do { \
- mutex_enter(&srv_sys.mutex); \
-} while (0)
-
-/** Release the system mutex. */
-#define srv_sys_mutex_exit() do { \
- mutex_exit(&srv_sys.mutex); \
-} while (0)
-
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -548,8 +533,6 @@ struct srv_sys_t{
UT_LIST_BASE_NODE_T(que_thr_t)
tasks; /*!< task queue */
- ib_mutex_t mutex; /*!< variable protecting the
- fields below. */
srv_stats_t::ulint_ctr_1_t
activity_count; /*!< For tracking server
activity */
@@ -585,16 +568,6 @@ and/or load it during startup. */
char srv_buffer_pool_dump_at_shutdown = TRUE;
char srv_buffer_pool_load_at_startup = TRUE;
-/** Slot index in the srv_sys.sys_threads array for the master thread. */
-#define SRV_MASTER_SLOT 0
-
-/** Slot index in the srv_sys.sys_threads array for the purge thread. */
-#define SRV_PURGE_SLOT 1
-
-/** Slot index in the srv_sys.sys_threads array from which purge workers start.
- */
-#define SRV_WORKER_SLOTS_START 2
-
#ifdef HAVE_PSI_STAGE_INTERFACE
/** Performance schema stage event for monitoring ALTER TABLE progress
everything after flush log_make_checkpoint(). */
@@ -724,16 +697,10 @@ static bool need_srv_free;
static void srv_init()
{
mutex_create(LATCH_ID_SRV_INNODB_MONITOR, &srv_innodb_monitor_mutex);
- srv_thread_pool_init();
if (!srv_read_only_mode) {
- mutex_create(LATCH_ID_SRV_SYS, &srv_sys.mutex);
-
mutex_create(LATCH_ID_SRV_SYS_TASKS, &srv_sys.tasks_mutex);
-
- buf_flush_event = os_event_create("buf_flush_event");
-
UT_LIST_INIT(srv_sys.tasks, &que_thr_t::queue);
}
@@ -778,9 +745,7 @@ srv_free(void)
mutex_free(&page_zip_stat_per_index_mutex);
if (!srv_read_only_mode) {
- mutex_free(&srv_sys.mutex);
mutex_free(&srv_sys.tasks_mutex);
- os_event_destroy(buf_flush_event);
}
ut_d(os_event_destroy(srv_master_thread_disabled_event));
@@ -795,6 +760,7 @@ void
srv_boot(void)
/*==========*/
{
+ srv_thread_pool_init();
sync_check_init();
trx_pool_init();
row_mysql_init();
@@ -1144,9 +1110,6 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_wait_free =
srv_stats.buf_pool_wait_free;
- export_vars.innodb_buffer_pool_pages_flushed =
- srv_stats.buf_pool_flushed;
-
export_vars.innodb_buffer_pool_reads = srv_stats.buf_pool_reads;
export_vars.innodb_buffer_pool_read_ahead_rnd =
@@ -1262,8 +1225,6 @@ srv_export_innodb_status(void)
export_vars.innodb_system_rows_deleted =
srv_stats.n_system_rows_deleted;
- export_vars.innodb_num_open_files = fil_system.n_open;
-
export_vars.innodb_truncated_status_writes =
srv_truncated_status_writes;
@@ -1320,13 +1281,13 @@ srv_export_innodb_status(void)
mutex_exit(&srv_innodb_monitor_mutex);
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
export_vars.innodb_lsn_current = log_sys.get_lsn();
export_vars.innodb_lsn_flushed = log_sys.get_flushed_lsn();
export_vars.innodb_lsn_last_checkpoint = log_sys.last_checkpoint_lsn;
export_vars.innodb_checkpoint_max_age = static_cast<ulint>(
log_sys.max_checkpoint_age);
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
export_vars.innodb_checkpoint_age = static_cast<ulint>(
export_vars.innodb_lsn_current
@@ -1513,7 +1474,6 @@ void
srv_wake_purge_thread_if_not_active()
{
ut_ad(!srv_read_only_mode);
- ut_ad(!mutex_own(&srv_sys.mutex));
if (purge_sys.enabled() && !purge_sys.paused()
&& trx_sys.rseg_history_len) {
@@ -1584,8 +1544,7 @@ void purge_sys_t::resume()
}
/*******************************************************************//**
-Get current server activity count. We don't hold srv_sys::mutex while
-reading this value as it is only used in heuristics.
+Get current server activity count.
@return activity count. */
ulint
srv_get_activity_count(void)
@@ -1594,11 +1553,10 @@ srv_get_activity_count(void)
return(srv_sys.activity_count);
}
-/** Check if there has been any activity.
-@param[in,out] activity_count recent activity count to be returned
-if there is a change
-@return FALSE if no change in activity counter. */
-bool srv_check_activity(ulint *activity_count)
+/** Check if srv_inc_activity_count() has been called.
+@param activity_count copy of srv_sys.activity_count
+@return whether the activity_count had changed */
+static bool srv_check_activity(ulint *activity_count)
{
ulint new_activity_count= srv_sys.activity_count;
if (new_activity_count != *activity_count)
@@ -1798,28 +1756,6 @@ srv_master_do_active_tasks(void)
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time);
}
-
- /* The periodic log_checkpoint() call here makes it harder to
- reproduce bugs in crash recovery or mariabackup --prepare, or
- in code that writes the redo log records. Omitting the call
- here should not affect correctness, because log_free_check()
- should still be invoking checkpoints when needed. In a
- production server, those calls could cause "furious flushing"
- and stall the server. Normally we want to perform checkpoints
- early and often to avoid those situations. */
- DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
-
- if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
- return;
- }
-
- /* Make a new checkpoint */
- if (cur_time % SRV_MASTER_CHECKPOINT_INTERVAL == 0) {
- srv_main_thread_op_info = "making checkpoint";
- log_checkpoint();
- MONITOR_INC_TIME_IN_MICRO_SECS(
- MONITOR_SRV_CHECKPOINT_MICROSECOND, counter_time);
- }
}
/*********************************************************************//**
@@ -1878,30 +1814,6 @@ srv_master_do_idle_tasks(void)
srv_sync_log_buffer_in_background();
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time);
-
- /* The periodic log_checkpoint() call here makes it harder to
- reproduce bugs in crash recovery or mariabackup --prepare, or
- in code that writes the redo log records. Omitting the call
- here should not affect correctness, because log_free_check()
- should still be invoking checkpoints when needed. In a
- production server, those calls could cause "furious flushing"
- and stall the server. Normally we want to perform checkpoints
- early and often to avoid those situations. */
- DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", return;);
-
- if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
- return;
- }
-
- /* Make a new checkpoint */
- srv_main_thread_op_info = "making checkpoint";
- log_checkpoint();
- MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_CHECKPOINT_MICROSECOND,
- counter_time);
-
- /* This is a workaround to avoid the InnoDB hang when OS datetime
- changed backwards.*/
- os_event_set(buf_flush_event);
}
/**
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 229f4879bf8..b53c7888509 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -140,30 +140,8 @@ UNIV_INTERN uint srv_sys_space_size_debug;
UNIV_INTERN bool srv_log_file_created;
#endif /* UNIV_DEBUG */
-/** Bit flags for tracking background thread creation. They are used to
-determine which threads need to be stopped if we need to abort during
-the initialisation step. */
-enum srv_start_state_t {
- /** No thread started */
- SRV_START_STATE_NONE = 0, /*!< No thread started */
- /** lock_wait_timeout timer task started */
- SRV_START_STATE_LOCK_SYS = 1,
- /** buf_flush_page_cleaner_coordinator,
- buf_flush_page_cleaner_worker started */
- SRV_START_STATE_IO = 2,
- /** srv_error_monitor_thread, srv_print_monitor_task started */
- SRV_START_STATE_MONITOR = 4,
- /** srv_master_thread started */
- SRV_START_STATE_MASTER = 8,
- /** srv_purge_coordinator_thread, srv_worker_thread started */
- SRV_START_STATE_PURGE = 16,
- /** fil_crypt_thread,
- (all background threads that can generate redo log but not undo log */
- SRV_START_STATE_REDO = 32
-};
-
-/** Track server thrd starting phases */
-static ulint srv_start_state;
+/** whether some background threads that create redo log have been started */
+static bool srv_started_redo;
/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
@@ -251,10 +229,12 @@ srv_file_check_mode(
static const char INIT_LOG_FILE0[]= "101";
/** Creates log file.
-@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value
-@param[out] logfile0 name of the log file
+@param[in] create_new_db whether the database is being initialized
+@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value
+@param[out] logfile0 name of the log file
@return DB_SUCCESS or error code */
-static dberr_t create_log_file(lsn_t lsn, std::string& logfile0)
+static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
+ std::string& logfile0)
{
if (srv_read_only_mode) {
ib::error() << "Cannot create log file in read-only mode";
@@ -318,10 +298,12 @@ static dberr_t create_log_file(lsn_t lsn, std::string& logfile0)
}
log_sys.log.open_file(logfile0);
- fil_open_system_tablespace_files();
+ if (!fil_system.sys_space->open(create_new_db)) {
+ return DB_ERROR;
+ }
/* Create a log checkpoint. */
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
if (log_sys.is_encrypted() && !log_crypt_init()) {
return DB_ERROR;
}
@@ -346,9 +328,10 @@ static dberr_t create_log_file(lsn_t lsn, std::string& logfile0)
log_sys.log.write_header_durable(lsn);
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
log_make_checkpoint();
+ log_write_up_to(LSN_MAX, true);
return DB_SUCCESS;
}
@@ -372,12 +355,12 @@ static dberr_t create_log_file_rename(lsn_t lsn, std::string &logfile0)
ib::info() << "Renaming log file " << logfile0 << " to " << new_name;
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
ut_ad(logfile0.size() == 2 + new_name.size());
logfile0= new_name;
dberr_t err= log_sys.log.rename(std::move(new_name));
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
DBUG_EXECUTE_IF("innodb_log_abort_10", err= DB_ERROR;);
@@ -574,8 +557,8 @@ err_exit:
fil_set_max_space_id_if_bigger(space_id);
- fil_space_t *space= fil_space_create(undo_name, space_id, fsp_flags,
- FIL_TYPE_TABLESPACE, NULL);
+ fil_space_t *space= fil_space_t::create(undo_name, space_id, fsp_flags,
+ FIL_TYPE_TABLESPACE, NULL);
ut_a(fil_validate());
ut_a(space);
@@ -584,20 +567,15 @@ err_exit:
if (create)
{
- space->size= file->size= ulint(size >> srv_page_size_shift);
- space->size_in_header= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
- space->committed_size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
+ space->set_sizes(SRV_UNDO_TABLESPACE_SIZE_IN_PAGES);
+ space->size= file->size= uint32_t(size >> srv_page_size_shift);
}
- else
+ else if (!file->read_page0())
{
- success= file->read_page0(true);
- if (!success)
- {
- os_file_close(file->handle);
- file->handle= OS_FILE_CLOSED;
- ut_a(fil_system.n_open > 0);
- fil_system.n_open--;
- }
+ os_file_close(file->handle);
+ file->handle= OS_FILE_CLOSED;
+ ut_a(fil_system.n_open > 0);
+ fil_system.n_open--;
}
mutex_exit(&fil_system.mutex);
@@ -824,7 +802,7 @@ srv_open_tmp_tablespace(bool create_new_db)
true, create_new_db, &sum_of_new_sizes, NULL))
!= DB_SUCCESS) {
ib::error() << "Unable to create the shared innodb_temporary";
- } else if (fil_system.temp_space->open()) {
+ } else if (fil_system.temp_space->open(true)) {
/* Initialize the header page */
mtr_t mtr;
mtr.start();
@@ -844,35 +822,8 @@ srv_open_tmp_tablespace(bool create_new_db)
return(err);
}
-/****************************************************************//**
-Set state to indicate start of particular group of threads in InnoDB. */
-UNIV_INLINE
-void
-srv_start_state_set(
-/*================*/
- srv_start_state_t state) /*!< in: indicate current state of
- thread startup */
-{
- srv_start_state |= ulint(state);
-}
-
-/****************************************************************//**
-Check if following group of threads is started.
-@return true if started */
-UNIV_INLINE
-bool
-srv_start_state_is_set(
-/*===================*/
- srv_start_state_t state) /*!< in: state to check for */
-{
- return(srv_start_state & ulint(state));
-}
-
-/**
-Shutdown all background threads created by InnoDB. */
-static
-void
-srv_shutdown_all_bg_threads()
+/** Shutdown background threads, except the page cleaner. */
+static void srv_shutdown_threads()
{
ut_ad(!srv_undo_sources);
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
@@ -884,45 +835,9 @@ srv_shutdown_all_bg_threads()
srv_purge_shutdown();
}
- /* All threads end up waiting for certain events. Put those events
- to the signaled state. Then the threads will exit themselves after
- os_event_wait(). */
- for (uint i = 0; i < 1000; ++i) {
- /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
- HERE OR EARLIER */
-
- if (!srv_read_only_mode) {
- /* b. srv error monitor thread exits automatically,
- no need to do anything here */
- if (srv_n_fil_crypt_threads_started) {
- os_event_set(fil_crypt_threads_event);
- }
- }
-
- if (srv_start_state_is_set(SRV_START_STATE_IO)) {
- ut_ad(!srv_read_only_mode);
-
- /* e. Exit the i/o threads */
- if (recv_sys.flush_start != NULL) {
- os_event_set(recv_sys.flush_start);
- }
- if (recv_sys.flush_end != NULL) {
- os_event_set(recv_sys.flush_end);
- }
-
- os_event_set(buf_flush_event);
- }
-
- if (!os_thread_count) {
- return;
- }
-
- os_thread_sleep(100000);
+ if (srv_n_fil_crypt_threads) {
+ fil_crypt_set_thread_cnt(0);
}
-
- ib::warn() << os_thread_count << " threads created by InnoDB"
- " had not exited at shutdown!";
- ut_ad(0);
}
#ifdef UNIV_DEBUG
@@ -969,7 +884,7 @@ srv_init_abort_low(
}
srv_shutdown_bg_undo_sources();
- srv_shutdown_all_bg_threads();
+ srv_shutdown_threads();
return(err);
}
@@ -995,7 +910,7 @@ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists)
DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0););
DBUG_PRINT("ib_log", ("After innodb_log_abort_1"));
- log_mutex_enter();
+ mysql_mutex_lock(&log_sys.mutex);
fil_names_clear(log_sys.get_lsn(), false);
@@ -1034,7 +949,7 @@ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists)
<< " bytes; LSN=" << flushed_lsn;
}
- log_mutex_exit();
+ mysql_mutex_unlock(&log_sys.mutex);
if (flushed_lsn != log_sys.get_flushed_lsn()) {
log_write_up_to(flushed_lsn, false);
@@ -1152,8 +1067,7 @@ dberr_t srv_start(bool create_new_db)
|| srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE
|| srv_sys_space.created_new_raw();
- /* Reset the start state. */
- srv_start_state = SRV_START_STATE_NONE;
+ srv_started_redo = false;
compile_time_assert(sizeof(ulint) == sizeof(void*));
@@ -1208,7 +1122,6 @@ dberr_t srv_start(bool create_new_db)
+ 1 /* buf_dump_thread */
+ 1 /* dict_stats_thread */
+ 1 /* fts_optimize_thread */
- + 1 /* recv_writer_thread */
+ 1 /* trx_rollback_all_recovered */
+ 128 /* added as margin, for use of
InnoDB Memcached etc. */
@@ -1336,12 +1249,7 @@ dberr_t srv_start(bool create_new_db)
if (!srv_read_only_mode) {
buf_flush_page_cleaner_init();
-
-#ifdef UNIV_LINUX
- /* Wait for the setpriority() call to finish. */
- os_event_wait(recv_sys.flush_end);
-#endif /* UNIV_LINUX */
- srv_start_state_set(SRV_START_STATE_IO);
+ ut_ad(buf_page_cleaner_is_active);
}
srv_startup_is_before_trx_rollback_phase = !create_new_db;
@@ -1389,13 +1297,13 @@ dberr_t srv_start(bool create_new_db)
}
std::string logfile0;
+ bool create_new_log = create_new_db;
if (create_new_db) {
-
+ flushed_lsn = log_sys.get_lsn();
+ log_sys.set_flushed_lsn(flushed_lsn);
buf_flush_sync();
- flushed_lsn = log_get_lsn();
-
- err = create_log_file(flushed_lsn, logfile0);
+ err = create_log_file(true, flushed_lsn, logfile0);
if (err != DB_SUCCESS) {
return(srv_init_abort(err));
@@ -1411,7 +1319,8 @@ dberr_t srv_start(bool create_new_db)
return srv_init_abort(err);
}
- if (srv_log_file_size == 0) {
+ create_new_log = srv_log_file_size == 0;
+ if (create_new_log) {
if (flushed_lsn < lsn_t(1000)) {
ib::error()
<< "Cannot create log file because"
@@ -1423,7 +1332,7 @@ dberr_t srv_start(bool create_new_db)
srv_log_file_size = srv_log_file_size_requested;
- err = create_log_file(flushed_lsn, logfile0);
+ err = create_log_file(false, flushed_lsn, logfile0);
if (err == DB_SUCCESS) {
err = create_log_file_rename(flushed_lsn,
@@ -1454,11 +1363,11 @@ dberr_t srv_start(bool create_new_db)
file_checked:
/* Open log file and data files in the systemtablespace: we keep
them open until database shutdown */
-
- fil_open_system_tablespace_files();
ut_d(fil_system.sys_space->recv_size = srv_sys_space_size_debug);
- err = srv_undo_tablespaces_init(create_new_db);
+ err = fil_system.sys_space->open(create_new_db)
+ ? srv_undo_tablespaces_init(create_new_db)
+ : DB_ERROR;
/* If the force recovery is set very high then we carry on regardless
of all errors. Basically this is fingers crossed mode. */
@@ -1484,7 +1393,8 @@ file_checked:
ut_ad(fil_system.sys_space->id == 0);
compile_time_assert(TRX_SYS_SPACE == 0);
compile_time_assert(IBUF_SPACE_ID == 0);
- fsp_header_init(fil_system.sys_space, sum_of_new_sizes, &mtr);
+ fsp_header_init(fil_system.sys_space,
+ uint32_t(sum_of_new_sizes), &mtr);
ulint ibuf_root = btr_create(
DICT_CLUSTERED | DICT_IBUF, fil_system.sys_space,
@@ -1525,10 +1435,17 @@ file_checked:
return(srv_init_abort(err));
}
} else {
+ /* Suppress warnings in fil_space_t::create() for files
+ that are being read before dict_boot() has recovered
+ DICT_HDR_MAX_SPACE_ID. */
+ fil_system.space_id_reuse_warned = true;
+
/* We always try to do a recovery, even if the database had
been shut down normally: this is the normal startup path */
- err = recv_recovery_from_checkpoint_start(flushed_lsn);
+ err = create_new_log
+ ? DB_SUCCESS
+ : recv_recovery_from_checkpoint_start(flushed_lsn);
recv_sys.close_files();
recv_sys.dblwr.pages.clear();
@@ -1555,6 +1472,9 @@ file_checked:
if (err != DB_SUCCESS) {
return srv_init_abort(err);
}
+ if (srv_operation == SRV_OPERATION_RESTORE) {
+ break;
+ }
trx_lists_init_at_db_start();
break;
case SRV_OPERATION_RESTORE_DELTA:
@@ -1581,6 +1501,8 @@ file_checked:
}
}
+ fil_system.space_id_reuse_warned = false;
+
if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
@@ -1606,7 +1528,8 @@ file_checked:
mtr.write<4>(*block,
FSP_HEADER_OFFSET + FSP_SIZE
+ block->frame, size);
- fil_system.sys_space->size_in_header = size;
+ fil_system.sys_space->size_in_header
+ = uint32_t(size);
mtr.commit();
/* Immediately write the log record about
increased tablespace size to disk, so that it
@@ -1665,10 +1588,7 @@ file_checked:
}
}
- /* recv_recovery_from_checkpoint_finish needs trx lists which
- are initialized in trx_lists_init_at_db_start(). */
-
- recv_recovery_from_checkpoint_finish();
+ recv_sys.debug_free();
if (srv_operation == SRV_OPERATION_RESTORE
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT) {
@@ -1679,7 +1599,6 @@ file_checked:
InnoDB files is needed. */
ut_ad(!srv_force_recovery);
ut_ad(recv_no_log_write);
- buf_flush_sync();
err = fil_write_flushed_lsn(log_get_lsn());
DBUG_ASSERT(!buf_pool.any_io_pending());
log_sys.log.close_file();
@@ -1753,7 +1672,7 @@ file_checked:
srv_log_file_size = srv_log_file_size_requested;
- err = create_log_file(flushed_lsn, logfile0);
+ err = create_log_file(false, flushed_lsn, logfile0);
if (err == DB_SUCCESS) {
err = create_log_file_rename(flushed_lsn,
@@ -1771,7 +1690,7 @@ file_checked:
/* Create the doublewrite buffer to a new tablespace */
if (!srv_read_only_mode && srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
- && !buf_dblwr_create()) {
+ && !buf_dblwr.create()) {
return(srv_init_abort(DB_ERROR));
}
@@ -1893,7 +1812,7 @@ file_checked:
/* Rollback incomplete non-DDL transactions */
trx_rollback_is_active = true;
- os_thread_create(trx_rollback_all_recovered, 0, 0);
+ os_thread_create(trx_rollback_all_recovered);
}
}
@@ -1910,9 +1829,6 @@ file_checked:
srv_start_periodic_timer(srv_error_monitor_timer, srv_error_monitor_task, 1000);
srv_start_periodic_timer(srv_monitor_timer, srv_monitor_task, 5000);
- srv_start_state |= SRV_START_STATE_LOCK_SYS
- | SRV_START_STATE_MONITOR;
-
#ifndef DBUG_OFF
skip_monitors:
#endif
@@ -1971,16 +1887,10 @@ skip_monitors:
srv_init_purge_tasks();
purge_sys.coordinator_startup();
srv_wake_purge_thread_if_not_active();
- srv_start_state_set(SRV_START_STATE_PURGE);
}
srv_is_being_started = false;
- if (!srv_read_only_mode) {
- /* wake main loop of page cleaner up */
- os_event_set(buf_flush_event);
- }
-
if (srv_print_verbose_log) {
ib::info() << INNODB_VERSION_STR
<< " started; log sequence number "
@@ -2035,7 +1945,7 @@ skip_monitors:
/* Initialize online defragmentation. */
btr_defragment_init();
- srv_start_state |= SRV_START_STATE_REDO;
+ srv_started_redo = true;
}
return(DB_SUCCESS);
@@ -2044,9 +1954,10 @@ skip_monitors:
/** Shut down background threads that can generate undo log. */
void srv_shutdown_bg_undo_sources()
{
+ srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
+
if (srv_undo_sources) {
ut_ad(!srv_read_only_mode);
- srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
fts_optimize_shutdown();
dict_stats_shutdown();
while (row_get_background_drop_list_len_low()) {
@@ -2076,11 +1987,15 @@ void innodb_preshutdown()
better prevent any further changes from being buffered. */
innodb_change_buffering= 0;
- while (trx_sys.any_active_transactions())
- os_thread_sleep(1000);
+ if (trx_sys.is_initialised())
+ while (trx_sys.any_active_transactions())
+ os_thread_sleep(1000);
}
srv_shutdown_bg_undo_sources();
srv_purge_shutdown();
+
+ if (srv_n_fil_crypt_threads)
+ fil_crypt_set_thread_cnt(0);
}
@@ -2091,9 +2006,21 @@ void innodb_shutdown()
ut_ad(!srv_undo_sources);
switch (srv_operation) {
case SRV_OPERATION_BACKUP:
- case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_DELTA:
+ break;
+ case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT:
+ srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
+ if (!buf_page_cleaner_is_active) {
+ break;
+ }
+ mysql_mutex_lock(&buf_pool.flush_list_mutex);
+ while (buf_page_cleaner_is_active) {
+ mysql_cond_signal(&buf_pool.do_flush_list);
+ mysql_cond_wait(&buf_pool.done_flush_list,
+ &buf_pool.flush_list_mutex);
+ }
+ mysql_mutex_unlock(&buf_pool.flush_list_mutex);
break;
case SRV_OPERATION_NORMAL:
/* Shut down the persistent files. */
@@ -2101,9 +2028,10 @@ void innodb_shutdown()
}
os_aio_free();
- fil_close_all_files();
+ fil_space_t::close_all();
/* Exit any remaining threads. */
- srv_shutdown_all_bg_threads();
+ ut_ad(!buf_page_cleaner_is_active);
+ srv_shutdown_threads();
if (srv_monitor_file) {
my_fclose(srv_monitor_file, MYF(MY_WME));
@@ -2121,7 +2049,8 @@ void innodb_shutdown()
ut_ad(dict_sys.is_initialised() || !srv_was_started);
ut_ad(trx_sys.is_initialised() || !srv_was_started);
- ut_ad(buf_dblwr || !srv_was_started || srv_read_only_mode
+ ut_ad(buf_dblwr.is_initialised() || !srv_was_started
+ || srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
ut_ad(lock_sys.is_initialised() || !srv_was_started);
ut_ad(log_sys.is_initialised() || !srv_was_started);
@@ -2129,7 +2058,7 @@ void innodb_shutdown()
dict_stats_deinit();
- if (srv_start_state_is_set(SRV_START_STATE_REDO)) {
+ if (srv_started_redo) {
ut_ad(!srv_read_only_mode);
/* srv_shutdown_bg_undo_sources() already invoked
fts_optimize_shutdown(); dict_stats_shutdown(); */
@@ -2150,9 +2079,7 @@ void innodb_shutdown()
log_sys.close();
purge_sys.close();
trx_sys.close();
- if (buf_dblwr) {
- buf_dblwr_free();
- }
+ buf_dblwr.close();
lock_sys.close();
trx_pool_close();
@@ -2179,7 +2106,7 @@ void innodb_shutdown()
<< "; transaction id " << trx_sys.get_max_trx_id();
}
srv_thread_pool_end();
- srv_start_state = SRV_START_STATE_NONE;
+ srv_started_redo = false;
srv_was_started = false;
srv_start_has_been_called = false;
}
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index 1e8ef62b429..4b6f818000c 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -169,7 +169,7 @@ mutexes and read-write locks */
sync_array_t** sync_wait_array;
/** count of how many times an object has been signalled */
-static ulint sg_count;
+ulint sg_count;
#define sync_array_exit(a) mutex_exit(&(a)->mutex)
#define sync_array_enter(a) mutex_enter(&(a)->mutex)
@@ -860,15 +860,6 @@ sync_array_detect_deadlock(
#endif /* UNIV_DEBUG */
/**********************************************************************//**
-Increments the signalled count. */
-void
-sync_array_object_signalled()
-/*=========================*/
-{
- ++sg_count;
-}
-
-/**********************************************************************//**
Prints warnings of long semaphore waits to stderr.
@return TRUE if fatal semaphore wait threshold was exceeded */
static
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 9297819a35b..87646867319 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -452,29 +452,17 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(RW_LOCK_S);
LEVEL_MAP_INSERT(RW_LOCK_X);
LEVEL_MAP_INSERT(RW_LOCK_NOT_LOCKED);
- LEVEL_MAP_INSERT(SYNC_MONITOR_MUTEX);
LEVEL_MAP_INSERT(SYNC_ANY_LATCH);
- LEVEL_MAP_INSERT(SYNC_DOUBLEWRITE);
- LEVEL_MAP_INSERT(SYNC_BUF_FLUSH_LIST);
- LEVEL_MAP_INSERT(SYNC_BUF_PAGE_HASH);
- LEVEL_MAP_INSERT(SYNC_BUF_POOL);
LEVEL_MAP_INSERT(SYNC_POOL);
LEVEL_MAP_INSERT(SYNC_POOL_MANAGER);
LEVEL_MAP_INSERT(SYNC_SEARCH_SYS);
LEVEL_MAP_INSERT(SYNC_WORK_QUEUE);
LEVEL_MAP_INSERT(SYNC_FTS_TOKENIZE);
LEVEL_MAP_INSERT(SYNC_FTS_OPTIMIZE);
- LEVEL_MAP_INSERT(SYNC_FTS_BG_THREADS);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE_INIT);
LEVEL_MAP_INSERT(SYNC_RECV);
- LEVEL_MAP_INSERT(SYNC_LOG_FLUSH_ORDER);
- LEVEL_MAP_INSERT(SYNC_LOG);
- LEVEL_MAP_INSERT(SYNC_LOG_WRITE);
- LEVEL_MAP_INSERT(SYNC_PAGE_CLEANER);
LEVEL_MAP_INSERT(SYNC_PURGE_QUEUE);
LEVEL_MAP_INSERT(SYNC_TRX_SYS_HEADER);
- LEVEL_MAP_INSERT(SYNC_REC_LOCK);
- LEVEL_MAP_INSERT(SYNC_THREADS);
LEVEL_MAP_INSERT(SYNC_TRX);
LEVEL_MAP_INSERT(SYNC_RW_TRX_HASH_ELEMENT);
LEVEL_MAP_INSERT(SYNC_READ_VIEW);
@@ -508,9 +496,7 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_DICT);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE);
LEVEL_MAP_INSERT(SYNC_DICT_OPERATION);
- LEVEL_MAP_INSERT(SYNC_TRX_I_S_LAST_READ);
LEVEL_MAP_INSERT(SYNC_TRX_I_S_RWLOCK);
- LEVEL_MAP_INSERT(SYNC_RECV_WRITER);
LEVEL_MAP_INSERT(SYNC_LEVEL_VARYING);
LEVEL_MAP_INSERT(SYNC_NO_ORDER_CHECK);
@@ -740,21 +726,13 @@ LatchDebug::check_order(
/* Fall through */
- case SYNC_MONITOR_MUTEX:
case SYNC_RECV:
- case SYNC_FTS_BG_THREADS:
case SYNC_WORK_QUEUE:
case SYNC_FTS_TOKENIZE:
case SYNC_FTS_OPTIMIZE:
case SYNC_FTS_CACHE:
case SYNC_FTS_CACHE_INIT:
- case SYNC_PAGE_CLEANER:
- case SYNC_LOG:
- case SYNC_LOG_WRITE:
- case SYNC_LOG_FLUSH_ORDER:
- case SYNC_DOUBLEWRITE:
case SYNC_SEARCH_SYS:
- case SYNC_THREADS:
case SYNC_LOCK_SYS:
case SYNC_LOCK_WAIT_SYS:
case SYNC_RW_TRX_HASH_ELEMENT:
@@ -768,14 +746,11 @@ LatchDebug::check_order(
case SYNC_DICT_OPERATION:
case SYNC_DICT_HEADER:
case SYNC_TRX_I_S_RWLOCK:
- case SYNC_TRX_I_S_LAST_READ:
case SYNC_IBUF_MUTEX:
case SYNC_INDEX_ONLINE_LOG:
case SYNC_STATS_AUTO_RECALC:
case SYNC_POOL:
case SYNC_POOL_MANAGER:
- case SYNC_RECV_WRITER:
- case SYNC_BUF_PAGE_HASH:
basic_check(latches, level, level);
break;
@@ -814,24 +789,6 @@ LatchDebug::check_order(
}
break;
- case SYNC_BUF_FLUSH_LIST:
- case SYNC_BUF_POOL:
-
- /* We can have multiple mutexes of this type therefore we
- can only check whether the greater than condition holds. */
-
- basic_check(latches, level, level - 1);
- break;
-
- case SYNC_REC_LOCK:
-
- if (find(latches, SYNC_LOCK_SYS) != 0) {
- basic_check(latches, level, SYNC_REC_LOCK - 1);
- } else {
- basic_check(latches, level, SYNC_REC_LOCK);
- }
- break;
-
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
@@ -1181,8 +1138,7 @@ sync_check_iterate(const sync_check_functor_t& functor)
Note: We don't enforce any synchronisation checks. The caller must ensure
that no races can occur */
-void
-sync_check_enable()
+static void sync_check_enable()
{
if (!srv_sync_debug) {
@@ -1250,16 +1206,11 @@ void
sync_latch_meta_init()
UNIV_NOTHROW
{
- latch_meta.resize(LATCH_ID_MAX);
+ latch_meta.resize(LATCH_ID_MAX + 1);
/* The latches should be ordered on latch_id_t. So that we can
index directly into the vector to update and fetch meta-data. */
- LATCH_ADD_MUTEX(BUF_POOL, SYNC_BUF_POOL, buf_pool_mutex_key);
-
- LATCH_ADD_MUTEX(CACHE_LAST_READ, SYNC_TRX_I_S_LAST_READ,
- cache_last_read_mutex_key);
-
LATCH_ADD_MUTEX(DICT_FOREIGN_ERR, SYNC_NO_ORDER_CHECK,
dict_foreign_err_mutex_key);
@@ -1267,16 +1218,8 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(FIL_SYSTEM, SYNC_ANY_LATCH, fil_system_mutex_key);
- LATCH_ADD_MUTEX(FLUSH_LIST, SYNC_BUF_FLUSH_LIST, flush_list_mutex_key);
-
- LATCH_ADD_MUTEX(FTS_BG_THREADS, SYNC_FTS_BG_THREADS,
- fts_bg_threads_mutex_key);
-
LATCH_ADD_MUTEX(FTS_DELETE, SYNC_FTS_OPTIMIZE, fts_delete_mutex_key);
- LATCH_ADD_MUTEX(FTS_OPTIMIZE, SYNC_FTS_OPTIMIZE,
- fts_optimize_mutex_key);
-
LATCH_ADD_MUTEX(FTS_DOC_ID, SYNC_FTS_OPTIMIZE, fts_doc_id_mutex_key);
LATCH_ADD_MUTEX(FTS_PLL_TOKENIZE, SYNC_FTS_TOKENIZE,
@@ -1290,18 +1233,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(IBUF_PESSIMISTIC_INSERT, SYNC_IBUF_PESS_INSERT_MUTEX,
ibuf_pessimistic_insert_mutex_key);
- LATCH_ADD_MUTEX(LOG_SYS, SYNC_LOG, log_sys_mutex_key);
-
- LATCH_ADD_MUTEX(LOG_WRITE, SYNC_LOG_WRITE, log_sys_write_mutex_key);
-
- LATCH_ADD_MUTEX(LOG_FLUSH_ORDER, SYNC_LOG_FLUSH_ORDER,
- log_flush_order_mutex_key);
-
- LATCH_ADD_MUTEX(MUTEX_LIST, SYNC_NO_ORDER_CHECK, mutex_list_mutex_key);
-
- LATCH_ADD_MUTEX(PAGE_CLEANER, SYNC_PAGE_CLEANER,
- page_cleaner_mutex_key);
-
LATCH_ADD_MUTEX(PURGE_SYS_PQ, SYNC_PURGE_QUEUE,
purge_sys_pq_mutex_key);
@@ -1310,8 +1241,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(RECV_SYS, SYNC_RECV, recv_sys_mutex_key);
- LATCH_ADD_MUTEX(RECV_WRITER, SYNC_RECV_WRITER, recv_writer_mutex_key);
-
LATCH_ADD_MUTEX(REDO_RSEG, SYNC_REDO_RSEG, redo_rseg_mutex_key);
LATCH_ADD_MUTEX(NOREDO_RSEG, SYNC_NOREDO_RSEG, noredo_rseg_mutex_key);
@@ -1335,8 +1264,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(RW_LOCK_LIST, SYNC_NO_ORDER_CHECK,
rw_lock_list_mutex_key);
- LATCH_ADD_MUTEX(RW_LOCK_MUTEX, SYNC_NO_ORDER_CHECK, rw_lock_mutex_key);
-
LATCH_ADD_MUTEX(SRV_INNODB_MONITOR, SYNC_NO_ORDER_CHECK,
srv_innodb_monitor_mutex_key);
@@ -1346,8 +1273,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(SRV_MONITOR_FILE, SYNC_NO_ORDER_CHECK,
srv_monitor_file_mutex_key);
- LATCH_ADD_MUTEX(BUF_DBLWR, SYNC_DOUBLEWRITE, buf_dblwr_mutex_key);
-
LATCH_ADD_MUTEX(TRX_POOL, SYNC_POOL, trx_pool_mutex_key);
LATCH_ADD_MUTEX(TRX_POOL_MANAGER, SYNC_POOL_MANAGER,
@@ -1362,41 +1287,14 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(TRX_SYS, SYNC_TRX_SYS, trx_sys_mutex_key);
- LATCH_ADD_MUTEX(SRV_SYS, SYNC_THREADS, srv_sys_mutex_key);
-
LATCH_ADD_MUTEX(SRV_SYS_TASKS, SYNC_ANY_LATCH, srv_threads_mutex_key);
LATCH_ADD_MUTEX(PAGE_ZIP_STAT_PER_INDEX, SYNC_ANY_LATCH,
page_zip_stat_per_index_mutex_key);
-#ifndef PFS_SKIP_EVENT_MUTEX
- LATCH_ADD_MUTEX(EVENT_MANAGER, SYNC_NO_ORDER_CHECK,
- event_manager_mutex_key);
-#else
- LATCH_ADD_MUTEX(EVENT_MANAGER, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-#endif /* !PFS_SKIP_EVENT_MUTEX */
-
- LATCH_ADD_MUTEX(EVENT_MUTEX, SYNC_NO_ORDER_CHECK, event_mutex_key);
-
LATCH_ADD_MUTEX(SYNC_ARRAY_MUTEX, SYNC_NO_ORDER_CHECK,
sync_array_mutex_key);
- LATCH_ADD_MUTEX(OS_AIO_READ_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
- LATCH_ADD_MUTEX(OS_AIO_WRITE_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
- LATCH_ADD_MUTEX(OS_AIO_LOG_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
- LATCH_ADD_MUTEX(OS_AIO_IBUF_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
- LATCH_ADD_MUTEX(OS_AIO_SYNC_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
LATCH_ADD_MUTEX(ROW_DROP_LIST, SYNC_NO_ORDER_CHECK,
row_drop_list_mutex_key);
@@ -1436,15 +1334,7 @@ sync_latch_meta_init()
LATCH_ADD_RWLOCK(INDEX_TREE, SYNC_INDEX_TREE, index_tree_rw_lock_key);
- LATCH_ADD_RWLOCK(DICT_TABLE_STATS, SYNC_INDEX_TREE,
- dict_table_stats_key);
-
- LATCH_ADD_MUTEX(SYNC_DEBUG_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
-
/* JAN: TODO: Add PFS instrumentation */
- LATCH_ADD_MUTEX(SCRUB_STAT_MUTEX, SYNC_NO_ORDER_CHECK,
- PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
LATCH_ADD_MUTEX(BTR_DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK,
@@ -1514,6 +1404,8 @@ sync_check_init()
ut_d(LatchDebug::init());
sync_array_init();
+
+ ut_d(sync_check_enable());
}
/** Free the InnoDB synchronization data structures. */
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index 4894b625db8..c2957a3fdcb 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -37,29 +37,22 @@ Created 9/5/1995 Heikki Tuuri
#ifdef UNIV_PFS_MUTEX
mysql_pfs_key_t buf_pool_mutex_key;
-mysql_pfs_key_t cache_last_read_mutex_key;
mysql_pfs_key_t dict_foreign_err_mutex_key;
mysql_pfs_key_t dict_sys_mutex_key;
mysql_pfs_key_t fil_system_mutex_key;
mysql_pfs_key_t flush_list_mutex_key;
-mysql_pfs_key_t fts_bg_threads_mutex_key;
mysql_pfs_key_t fts_delete_mutex_key;
-mysql_pfs_key_t fts_optimize_mutex_key;
mysql_pfs_key_t fts_doc_id_mutex_key;
mysql_pfs_key_t fts_pll_tokenize_mutex_key;
mysql_pfs_key_t ibuf_bitmap_mutex_key;
mysql_pfs_key_t ibuf_mutex_key;
mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
mysql_pfs_key_t log_sys_mutex_key;
-mysql_pfs_key_t log_sys_write_mutex_key;
mysql_pfs_key_t log_cmdq_mutex_key;
mysql_pfs_key_t log_flush_order_mutex_key;
-mysql_pfs_key_t mutex_list_mutex_key;
mysql_pfs_key_t recalc_pool_mutex_key;
-mysql_pfs_key_t page_cleaner_mutex_key;
mysql_pfs_key_t purge_sys_pq_mutex_key;
mysql_pfs_key_t recv_sys_mutex_key;
-mysql_pfs_key_t recv_writer_mutex_key;
mysql_pfs_key_t redo_rseg_mutex_key;
mysql_pfs_key_t noredo_rseg_mutex_key;
mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
@@ -70,7 +63,6 @@ mysql_pfs_key_t rtr_active_mutex_key;
mysql_pfs_key_t rtr_match_mutex_key;
mysql_pfs_key_t rtr_path_mutex_key;
mysql_pfs_key_t rw_lock_list_mutex_key;
-mysql_pfs_key_t rw_lock_mutex_key;
mysql_pfs_key_t srv_innodb_monitor_mutex_key;
mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
mysql_pfs_key_t srv_monitor_file_mutex_key;
@@ -81,10 +73,7 @@ mysql_pfs_key_t trx_pool_manager_mutex_key;
mysql_pfs_key_t lock_mutex_key;
mysql_pfs_key_t lock_wait_mutex_key;
mysql_pfs_key_t trx_sys_mutex_key;
-mysql_pfs_key_t srv_sys_mutex_key;
mysql_pfs_key_t srv_threads_mutex_key;
-mysql_pfs_key_t event_mutex_key;
-mysql_pfs_key_t event_manager_mutex_key;
mysql_pfs_key_t sync_array_mutex_key;
mysql_pfs_key_t thread_mutex_key;
mysql_pfs_key_t row_drop_list_mutex_key;
@@ -98,7 +87,6 @@ mysql_pfs_key_t buf_block_lock_key;
mysql_pfs_key_t buf_block_debug_latch_key;
# endif /* UNIV_DEBUG */
mysql_pfs_key_t dict_operation_lock_key;
-mysql_pfs_key_t dict_table_stats_key;
mysql_pfs_key_t index_tree_rw_lock_key;
mysql_pfs_key_t index_online_log_key;
mysql_pfs_key_t fil_space_latch_key;
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index 82477399552..d3d2b742d84 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -141,12 +141,9 @@ struct i_s_table_cache_t {
struct trx_i_s_cache_t {
rw_lock_t rw_lock; /*!< read-write lock protecting
the rest of this structure */
- ulonglong last_read; /*!< last time the cache was read;
+ Atomic_relaxed<ulonglong> last_read;
+ /*!< last time the cache was read;
measured in nanoseconds */
- ib_mutex_t last_read_mutex;/*!< mutex protecting the
- last_read member - it is updated
- inside a shared lock of the
- rw_lock member */
i_s_table_cache_t innodb_trx; /*!< innodb_trx table */
i_s_table_cache_t innodb_locks; /*!< innodb_locks table */
i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
@@ -1136,8 +1133,7 @@ Checks if the cache can safely be updated.
@return whether the cache can be updated */
static bool can_cache_be_updated(trx_i_s_cache_t* cache)
{
- /* Here we read cache->last_read without acquiring its mutex
- because last_read is only updated when a shared rw lock on the
+ /* cache->last_read is only updated when a shared rw lock on the
whole cache is being held (see trx_i_s_cache_end_read()) and
we are currently holding an exclusive rw lock on the cache.
So it is not possible for last_read to be updated while we are
@@ -1269,8 +1265,6 @@ trx_i_s_cache_init(
release lock mutex
release trx_i_s_cache_t::rw_lock
acquire trx_i_s_cache_t::rw_lock, S
- acquire trx_i_s_cache_t::last_read_mutex
- release trx_i_s_cache_t::last_read_mutex
release trx_i_s_cache_t::rw_lock */
rw_lock_create(trx_i_s_cache_lock_key, &cache->rw_lock,
@@ -1278,8 +1272,6 @@ trx_i_s_cache_init(
cache->last_read = 0;
- mutex_create(LATCH_ID_CACHE_LAST_READ, &cache->last_read_mutex);
-
table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t));
table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t));
table_cache_init(&cache->innodb_lock_waits,
@@ -1303,7 +1295,6 @@ trx_i_s_cache_free(
trx_i_s_cache_t* cache) /*!< in, own: cache to free */
{
rw_lock_free(&cache->rw_lock);
- mutex_free(&cache->last_read_mutex);
cache->locks_hash.free();
ha_storage_free(cache->storage);
@@ -1329,14 +1320,7 @@ trx_i_s_cache_end_read(
/*===================*/
trx_i_s_cache_t* cache) /*!< in: cache */
{
- ut_ad(rw_lock_own(&cache->rw_lock, RW_LOCK_S));
-
- /* update cache last read time */
- const ulonglong now = my_interval_timer();
- mutex_enter(&cache->last_read_mutex);
- cache->last_read = now;
- mutex_exit(&cache->last_read_mutex);
-
+ cache->last_read = my_interval_timer();
rw_lock_s_unlock(&cache->rw_lock);
}
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 393f044d23a..c0375f25fa6 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -262,7 +262,7 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
or in trx_rollback_recovered() in slow shutdown.
Before any transaction-generating background threads or the
- purge have been started, recv_recovery_rollback_active() can
+ purge have been started, we can
start transactions in row_merge_drop_temp_indexes() and
fts_drop_orphaned_tables(), and roll back recovered transactions.
@@ -584,11 +584,10 @@ static void trx_purge_truncate_history()
: 0, j = i;; ) {
ulint space_id = srv_undo_space_id_start + i;
ut_ad(srv_is_undo_tablespace(space_id));
+ fil_space_t* space= fil_space_get(space_id);
- if (fil_space_get_size(space_id)
- > threshold) {
- purge_sys.truncate.current
- = fil_space_get(space_id);
+ if (space && space->get_size() > threshold) {
+ purge_sys.truncate.current = space;
break;
}
@@ -680,7 +679,7 @@ not_free:
mini-transaction commit and the server was killed, then
discarding the to-be-trimmed pages without flushing would
break crash recovery. So, we cannot avoid the write. */
- buf_LRU_flush_or_remove_pages(space.id, true);
+ while (buf_flush_dirty_pages(space.id));
log_free_check();
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index ba006f37bb5..52130b50eb1 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -129,20 +129,35 @@ trx_undo_log_v_idx(
{
ut_ad(pos < table->n_v_def);
dict_v_col_t* vcol = dict_table_get_nth_v_col(table, pos);
- ulint n_idx = vcol->n_v_indexes;
byte* old_ptr;
- ut_ad(n_idx > 0);
+ ut_ad(!vcol->v_indexes.empty());
/* Size to reserve, max 5 bytes for each index id and position, plus
5 bytes for num of indexes, 2 bytes for write total length.
1 byte for undo log record format version marker */
- ulint size = n_idx * (5 + 5) + 5 + 2 + (first_v_col ? 1 : 0);
+ ulint size = 5 + 2 + (first_v_col ? 1 : 0);
+ const ulint avail = trx_undo_left(undo_block, ptr);
- if (trx_undo_left(undo_block, ptr) < size) {
+ if (avail < size) {
return(NULL);
}
+ size = 0;
+ ulint n_idx = 0;
+ for (const auto& v_index : vcol->v_indexes) {
+ n_idx++;
+ /* FIXME: index->id is 64 bits! */
+ size += mach_get_compressed_size(uint32_t(v_index.index->id));
+ size += mach_get_compressed_size(v_index.nth_field);
+ }
+ size += 2 + mach_get_compressed_size(n_idx);
+
+ if (avail < size) {
+ return(NULL);
+ }
+
+
if (first_v_col) {
/* write the version marker */
mach_write_to_1(ptr, VIRTUAL_COL_UNDO_FORMAT_1);
@@ -158,7 +173,8 @@ trx_undo_log_v_idx(
for (const auto& v_index : vcol->v_indexes) {
ptr += mach_write_compressed(
- ptr, static_cast<ulint>(v_index.index->id));
+ /* FIXME: index->id is 64 bits! */
+ ptr, uint32_t(v_index.index->id));
ptr += mach_write_compressed(ptr, v_index.nth_field);
}
@@ -1896,8 +1912,6 @@ dberr_t trx_undo_report_rename(trx_t* trx, const dict_table_t* table)
if (uint16_t offset = trx_undo_page_report_rename(
trx, table, block, &mtr)) {
- undo->withdraw_clock
- = buf_pool.withdraw_clock();
undo->top_page_no = undo->last_page_no;
undo->top_offset = offset;
undo->top_undo_no = trx->undo_no++;
@@ -2060,7 +2074,6 @@ trx_undo_report_row_operation(
mtr_commit(&mtr);
} else {
/* Success */
- undo->withdraw_clock = buf_pool.withdraw_clock();
mtr_commit(&mtr);
undo->top_page_no = undo_block->page.id().page_no();
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index fb58687beab..2aee1636084 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -391,7 +391,7 @@ trx_rseg_mem_free(trx_rseg_t* rseg)
@param[in] page_no page number of the segment header */
static
trx_rseg_t*
-trx_rseg_mem_create(ulint id, fil_space_t* space, ulint page_no)
+trx_rseg_mem_create(ulint id, fil_space_t* space, uint32_t page_no)
{
trx_rseg_t* rseg = static_cast<trx_rseg_t*>(
ut_zalloc_nokey(sizeof *rseg));
@@ -418,12 +418,12 @@ trx_rseg_mem_create(ulint id, fil_space_t* space, ulint page_no)
@param[in,out] max_trx_id maximum observed transaction identifier
@param[in] rseg_header rollback segment header
@return the combined size of undo log segments in pages */
-static ulint trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
- const buf_block_t *rseg_header)
+static uint32_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
+ const buf_block_t *rseg_header)
{
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
- ulint size= 0;
+ uint32_t size= 0;
for (ulint i= 0; i < TRX_RSEG_N_SLOTS; i++)
{
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index a3ada6636fd..9011ca8f2e1 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -163,7 +163,7 @@ trx_sysf_create(
mtr);
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
- ut_a(block->page.id().page_no() == TRX_SYS_PAGE_NO);
+ ut_a(block->page.id() == page_id_t(0, TRX_SYS_PAGE_NO));
mtr->write<2>(*block, FIL_PAGE_TYPE + block->frame,
FIL_PAGE_TYPE_TRX_SYS);
@@ -195,7 +195,7 @@ trx_sysf_create(
slot_no, block, mtr);
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
- ut_a(rblock->page.id().page_no() == FSP_FIRST_RSEG_PAGE_NO);
+ ut_a(rblock->page.id() == page_id_t(0, FSP_FIRST_RSEG_PAGE_NO));
}
/** Create the instance */
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index ae3224a29a6..67e515127d0 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -237,8 +237,8 @@ trx_undo_get_next_rec_from_next_page(buf_block_t *&block, uint32_t page_no,
mach_read_from_2(block->frame + offset + TRX_UNDO_NEXT_LOG))
return NULL;
- ulint next= flst_get_next_addr(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE +
- block->frame).page;
+ uint32_t next= flst_get_next_addr(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE +
+ block->frame).page;
if (next == FIL_NULL)
return NULL;
@@ -359,7 +359,7 @@ trx_undo_seg_create(fil_space_t *space, buf_block_t *rseg_hdr, ulint *id,
dberr_t *err, mtr_t *mtr)
{
buf_block_t* block;
- ulint n_reserved;
+ uint32_t n_reserved;
bool success;
const ulint slot_no = trx_rsegf_undo_find_free(rseg_hdr);
@@ -551,7 +551,7 @@ buf_block_t* trx_undo_add_page(trx_undo_t* undo, mtr_t* mtr)
{
trx_rseg_t* rseg = undo->rseg;
buf_block_t* new_block = NULL;
- ulint n_reserved;
+ uint32_t n_reserved;
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
@@ -981,7 +981,6 @@ trx_undo_mem_create(
undo->top_undo_no = IB_ID_MAX;
undo->top_page_no = page_no;
undo->guess_block = NULL;
- undo->withdraw_clock = 0;
ut_ad(undo->empty());
return(undo);
@@ -1157,9 +1156,7 @@ trx_undo_assign(trx_t* trx, dberr_t* err, mtr_t* mtr)
if (undo) {
return buf_page_get_gen(
page_id_t(undo->rseg->space->id, undo->last_page_no),
- 0, RW_X_LATCH,
- buf_pool.is_obsolete(undo->withdraw_clock)
- ? NULL : undo->guess_block,
+ 0, RW_X_LATCH, undo->guess_block,
BUF_GET, __FILE__, __LINE__, mtr, err);
}
@@ -1213,9 +1210,7 @@ trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
if (*undo) {
return buf_page_get_gen(
page_id_t(rseg->space->id, (*undo)->last_page_no),
- 0, RW_X_LATCH,
- buf_pool.is_obsolete((*undo)->withdraw_clock)
- ? NULL : (*undo)->guess_block,
+ 0, RW_X_LATCH, (*undo)->guess_block,
BUF_GET, __FILE__, __LINE__, mtr, err);
}
diff --git a/storage/innobase/ut/ut0wqueue.cc b/storage/innobase/ut/ut0wqueue.cc
index ae97009430e..53bb0c8b148 100644
--- a/storage/innobase/ut/ut0wqueue.cc
+++ b/storage/innobase/ut/ut0wqueue.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 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,7 +44,6 @@ ib_wqueue_create(void)
mutex_create(LATCH_ID_WORK_QUEUE, &wq->mutex);
wq->items = ib_list_create();
- wq->event = os_event_create(0);
return(wq);
}
@@ -58,7 +57,6 @@ ib_wqueue_free(
{
mutex_free(&wq->mutex);
ib_list_free(wq->items);
- os_event_destroy(wq->event);
ut_free(wq);
}
@@ -76,93 +74,12 @@ ib_wqueue_add(ib_wqueue_t* wq, void* item, mem_heap_t* heap, bool wq_locked)
}
ib_list_add_last(wq->items, item, heap);
- os_event_set(wq->event);
if (!wq_locked) {
mutex_exit(&wq->mutex);
}
}
-/****************************************************************//**
-Wait for a work item to appear in the queue.
-@return work item */
-void*
-ib_wqueue_wait(
-/*===========*/
- ib_wqueue_t* wq) /*!< in: work queue */
-{
- ib_list_node_t* node;
-
- for (;;) {
- os_event_wait(wq->event);
-
- mutex_enter(&wq->mutex);
-
- node = ib_list_get_first(wq->items);
-
- if (node) {
- ib_list_remove(wq->items, node);
-
- if (!ib_list_get_first(wq->items)) {
- /* We must reset the event when the list
- gets emptied. */
- os_event_reset(wq->event);
- }
-
- break;
- }
-
- mutex_exit(&wq->mutex);
- }
-
- mutex_exit(&wq->mutex);
-
- return(node->data);
-}
-
-
-/********************************************************************
-Wait for a work item to appear in the queue for specified time. */
-void*
-ib_wqueue_timedwait(
-/*================*/
- /* out: work item or NULL on timeout*/
- ib_wqueue_t* wq, /* in: work queue */
- ulint wait_in_usecs) /* in: wait time in micro seconds */
-{
- ib_list_node_t* node = NULL;
-
- for (;;) {
- ulint error;
- int64_t sig_count;
-
- mutex_enter(&wq->mutex);
-
- node = ib_list_get_first(wq->items);
-
- if (node) {
- ib_list_remove(wq->items, node);
-
- mutex_exit(&wq->mutex);
- break;
- }
-
- sig_count = os_event_reset(wq->event);
-
- mutex_exit(&wq->mutex);
-
- error = os_event_wait_time_low(wq->event,
- (ulint) wait_in_usecs,
- sig_count);
-
- if (error == OS_SYNC_TIME_EXCEEDED) {
- break;
- }
- }
-
- return(node ? node->data : NULL);
-}
-
/********************************************************************
Return first item on work queue or NULL if queue is empty
@return work item or NULL */
@@ -180,16 +97,9 @@ ib_wqueue_nowait(
if (node) {
ib_list_remove(wq->items, node);
-
}
}
- /* We must reset the event when the list
- gets emptied. */
- if(ib_list_is_empty(wq->items)) {
- os_event_reset(wq->event);
- }
-
mutex_exit(&wq->mutex);
return (node ? node->data : NULL);
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt
index c21694a070c..f15ba313694 100644
--- a/storage/maria/CMakeLists.txt
+++ b/storage/maria/CMakeLists.txt
@@ -109,7 +109,8 @@ INCLUDE (CheckIncludeFiles)
SET(S3_SOURCES s3_func.c
libmarias3/src/debug.c libmarias3/src/error.c libmarias3/src/marias3.c
libmarias3/src/request.c libmarias3/src/response.c libmarias3/src/sha256.c
- libmarias3/src/sha256-internal.c libmarias3/src/xml.c)
+ libmarias3/src/sha256-internal.c libmarias3/src/xml.c
+ libmarias3/src/assume_role.c)
IF(NOT PLUGIN_S3 STREQUAL NO)
FIND_PACKAGE(CURL)
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 3c43595533f..8d57959e13a 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -72,7 +72,7 @@ const char *zerofill_error_msg=
corrupted.
*/
ulonglong maria_recover_options= HA_RECOVER_NONE;
-handlerton __attribute__((visibility("default"))) *maria_hton;
+handlerton *maria_hton;
/* bits in maria_recover_options */
const char *maria_recover_names[]=
@@ -1025,7 +1025,7 @@ int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_CAN_VIRTUAL_COLUMNS | HA_CAN_EXPORT |
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
HA_CAN_TABLES_WITHOUT_ROLLBACK),
-can_enable_indexes(1), bulk_insert_single_undo(BULK_INSERT_NONE)
+can_enable_indexes(0), bulk_insert_single_undo(BULK_INSERT_NONE)
{}
@@ -2103,6 +2103,7 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
DBUG_ENTER("ha_maria::start_bulk_insert");
THD *thd= table->in_use;
MARIA_SHARE *share= file->s;
+ bool index_disabled= 0;
DBUG_PRINT("info", ("start_bulk_insert: rows %lu", (ulong) rows));
/* don't enable row cache if too few rows */
@@ -2166,6 +2167,7 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
{
/* Internal table; If we get a duplicate something is very wrong */
file->update|= HA_STATE_CHANGED;
+ index_disabled= share->base.keys > 0;
maria_clear_all_keys_active(file->s->state.key_map);
}
else
@@ -2193,6 +2195,7 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
table->key_info[i].algorithm != HA_KEY_ALG_LONG_HASH)
{
maria_clear_key_active(share->state.key_map, i);
+ index_disabled= 1;
file->update|= HA_STATE_CHANGED;
file->create_unique_index_by_sort= all_keys;
}
@@ -2222,6 +2225,7 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
rows);
}
}
+ can_enable_indexes= index_disabled;
DBUG_VOID_RETURN;
}
@@ -2260,7 +2264,6 @@ int ha_maria::end_bulk_insert()
if (bulk_insert_single_undo != BULK_INSERT_NONE)
{
- DBUG_ASSERT(can_enable_indexes);
/*
Table was transactional just before start_bulk_insert().
No need to flush pages if we did a repair (which already flushed).
@@ -2271,6 +2274,7 @@ int ha_maria::end_bulk_insert()
first_error= first_error ? first_error : error;
bulk_insert_single_undo= BULK_INSERT_NONE; // Safety
}
+ can_enable_indexes= 0;
DBUG_RETURN(first_error);
}
@@ -2546,6 +2550,9 @@ int ha_maria::info(uint flag)
MARIA_INFO maria_info;
char name_buff[FN_REFLEN];
+ if (!file)
+ return 0;
+
(void) maria_status(file, &maria_info, flag);
if (flag & HA_STATUS_VARIABLE)
{
diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc
index 190d99035a5..cf2b9098142 100644
--- a/storage/maria/ha_s3.cc
+++ b/storage/maria/ha_s3.cc
@@ -51,7 +51,11 @@
but the stored block will be the size of the compressed block.
Implementation:
- The s3 engine inherits from the ha_maria handler
+ The s3 engine inherits from the ha_maria handler.
+
+ It uses Aria code and relies on Aria being enabled. We don't have to check
+ that Aria is enabled though, because Aria is a mandatory plugin, and
+ the server will refuse to start if Aria failed to initialize.
s3 will use it's own page cache to not interfere with normal Aria
usage but also to ensure that the S3 page cache is large enough
@@ -269,7 +273,7 @@ int ha_s3::write_row(const uchar *buf)
DBUG_ENTER("ha_s3::write_row");
if (in_alter_table)
DBUG_RETURN(ha_maria::write_row(buf));
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
/* Return true if S3 can be used */
@@ -576,7 +580,25 @@ int ha_s3::open(const char *name, int mode, uint open_flags)
if (!s3_usable())
DBUG_RETURN(HA_ERR_UNSUPPORTED);
- if (mode != O_RDONLY && !(open_flags & HA_OPEN_FOR_CREATE))
+ /*
+ On slaves with s3_slave_ignore_updates set we allow tables to be
+ opened in write mode to be able to ignore queries that modify
+ the table trough handler::check_if_updates_are_ignored().
+
+ This is needed for the slave to be able to handle
+ CREATE TABLE t1...
+ INSERT INTO TABLE t1 ....
+ ALTER TABLE t1 ENGINE=S3
+ If this is not done, the insert will fail on the slave if the
+ master has already executed the ALTER TABLE.
+
+ We also have to allow open for create, as part of
+ ALTER TABLE ... ENGINE=S3.
+
+ Otherwise we only allow the table to be open in read mode
+ */
+ if (mode != O_RDONLY && !(open_flags & HA_OPEN_FOR_CREATE) &&
+ !s3_slave_ignore_updates)
DBUG_RETURN(EACCES);
open_args= 0;
@@ -978,14 +1000,7 @@ static int ha_s3_init(void *p)
bool res;
static const char *no_exts[]= { 0 };
- /* This can happen if Aria fails to start */
- if (!maria_hton)
- return HA_ERR_INITIALIZATION;
-
s3_hton= (handlerton *)p;
-
- /* Use Aria engine as a base */
- memcpy(s3_hton, maria_hton, sizeof(*s3_hton));
s3_hton->db_type= DB_TYPE_S3;
s3_hton->create= s3_create_handler;
s3_hton->panic= s3_hton_panic;
@@ -1092,6 +1107,6 @@ maria_declare_plugin(s3)
status_variables, /* status variables */
system_variables, /* system variables */
"1.0", /* string version */
- MariaDB_PLUGIN_MATURITY_ALPHA /* maturity */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/maria/ha_s3.h b/storage/maria/ha_s3.h
index 0dd36609a9e..e16353b2a32 100644
--- a/storage/maria/ha_s3.h
+++ b/storage/maria/ha_s3.h
@@ -1,6 +1,6 @@
#ifndef HA_S3_INCLUDED
#define HA_S3_INCLUDED
-/* Copyright (C) 2019 MariaDB Corppration AB
+/* Copyright (C) 2019, 2020, MariaDB Corporation AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,52 +31,50 @@ public:
~ha_s3() {}
int create(const char *name, TABLE *table_arg,
- HA_CREATE_INFO *ha_create_info);
- int open(const char *name, int mode, uint open_flags);
- int write_row(const uchar *buf);
- int update_row(const uchar * old_data, const uchar * new_data)
+ HA_CREATE_INFO *ha_create_info) override;
+ int open(const char *name, int mode, uint open_flags) override;
+ int write_row(const uchar *buf) override;
+ int update_row(const uchar *, const uchar *) override
{
DBUG_ENTER("update_row");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int delete_row(const uchar * buf)
+ int delete_row(const uchar *) override
{
DBUG_ENTER("delete_row");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int check(THD * thd, HA_CHECK_OPT * check_opt)
+ int check(THD *, HA_CHECK_OPT *) override
{
DBUG_ENTER("delete_row");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int analyze(THD * thd, HA_CHECK_OPT * check_opt)
+ int analyze(THD *, HA_CHECK_OPT *) override
{
DBUG_ENTER("analyze");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int repair(THD * thd, HA_CHECK_OPT * check_opt)
+ int repair(THD *, HA_CHECK_OPT *) override
{
DBUG_ENTER("repair");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int preload_keys(THD * thd, HA_CHECK_OPT * check_opt)
+ int preload_keys(THD *, HA_CHECK_OPT *) override
{
DBUG_ENTER("preload_keys");
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
- int external_lock(THD * thd, int lock_type);
+ int external_lock(THD * thd, int lock_type) override;
/*
drop_table() is only used for internal temporary tables,
not applicable for s3
*/
- void drop_table(const char *name)
- {
- }
- int delete_table(const char *name);
- int rename_table(const char *from, const char *to);
+ void drop_table(const char *) override {}
+ int delete_table(const char *name) override;
+ int rename_table(const char *from, const char *to) override;
int discover_check_version() override;
int rebind();
- S3_INFO *s3_open_args() { return open_args; }
- void register_handler(MARIA_HA *file);
+ S3_INFO *s3_open_args() override { return open_args; }
+ void register_handler(MARIA_HA *file) override;
};
#endif /* HA_S3_INCLUDED */
diff --git a/storage/maria/libmarias3 b/storage/maria/libmarias3
-Subproject 7aa450e3a02a20ef62616666a2b582f4d07fb5b
+Subproject 0d48bf334fde7d4e0dac22bda560e86037d35d7
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 45865709cd3..2b390c6c267 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -2560,6 +2560,9 @@ static int maria_drop_all_indexes(HA_CHECK *param, MARIA_HA *info,
DBUG_PRINT("repair", ("declared all indexes disabled"));
}
+ /* Flush obsolete index data from key cache */
+ _ma_flush_table_files(info, MARIA_FLUSH_INDEX,
+ FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED);
/* Clear index root block pointers. */
for (i= 0; i < share->base.keys; i++)
state->key_root[i]= HA_OFFSET_ERROR;
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index d64dc8308c5..abac01d87a7 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -1174,6 +1174,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
FALSE, TRUE))
goto err;
my_free(log_data);
+ log_data= 0;
}
if (!(flags & HA_DONT_TOUCH_DATA))
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index b464cf4f94e..042a96efabf 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -229,6 +229,9 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
info->lock_wait= MY_SHORT_WAIT;
break;
case HA_EXTRA_NO_KEYS:
+ if (share->s3_path) /* Not supported with S3 */
+ break;
+
/* we're going to modify pieces of the state, stall Checkpoint */
mysql_mutex_lock(&share->intern_lock);
if (info->lock_type == F_UNLCK)
@@ -369,16 +372,16 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
if (end_io_cache(&info->rec_cache))
error= 1;
}
- if (share->kfile.file >= 0)
+ if (share->kfile.file >= 0 && share->s3_path == 0)
{
if (do_flush)
{
/* Save the state so that others can find it from disk. */
- if ((share->changed &&
- _ma_state_info_write(share,
+ if (share->changed &&
+ (_ma_state_info_write(share,
MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET |
- MA_STATE_INFO_WRITE_FULL_INFO)) ||
- mysql_file_sync(share->kfile.file, MYF(0)))
+ MA_STATE_INFO_WRITE_FULL_INFO) ||
+ mysql_file_sync(share->kfile.file, MYF(0))))
error= my_errno;
}
else
@@ -390,7 +393,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
}
}
if (share->data_file_type == BLOCK_RECORD &&
- share->bitmap.file.file >= 0)
+ share->bitmap.file.file >= 0 && share->s3_path == 0)
{
DBUG_ASSERT(share->bitmap.non_flushable == 0 &&
share->bitmap.changed == 0);
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index e7d6f97d57c..f32fd6dd19d 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -369,6 +369,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
#ifdef WITH_S3_STORAGE_ENGINE
else
{
+ open_mode= mode;
errpos= 1;
if (s3f.set_database_and_table_from_path(s3, name_buff))
{
@@ -1050,6 +1051,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
share->state_history->next= 0;
}
}
+ errpos= 7;
thr_lock_init(&share->lock);
mysql_mutex_init(key_SHARE_intern_lock,
&share->intern_lock, MY_MUTEX_INIT_FAST);
@@ -1193,6 +1195,9 @@ err:
_ma_report_error(save_errno, &tmp_name);
}
switch (errpos) {
+ case 7:
+ thr_lock_delete(&share->lock);
+ /* fall through */
case 6:
/* Avoid mutex test in _ma_bitmap_end() */
share->internal_table= 1;
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 0a55018db0f..bf646115bd9 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -2810,7 +2810,7 @@ static void read_big_block(PAGECACHE *pagecache,
if (block_to_read->status & PCBLOCK_ERROR)
{
/* We get first block with an error so all operation failed */
- goto error;
+ DBUG_VOID_RETURN;
}
if (block_to_read->status & PCBLOCK_BIG_READ)
{
@@ -2842,7 +2842,11 @@ static void read_big_block(PAGECACHE *pagecache,
// page should be read by other thread
DBUG_ASSERT(block->status & PCBLOCK_READ ||
block->status & PCBLOCK_ERROR);
- DBUG_ASSERT(block->status & PCBLOCK_BIG_READ);
+ /*
+ It is possible that other thread already removed the flag (in
+ case of two threads waiting) but it will not make harm to try to
+ remove it even in that case.
+ */
block->status&= ~PCBLOCK_BIG_READ;
// all is read => lets finish nice
DBUG_ASSERT(block_to_read != block);
@@ -2960,9 +2964,8 @@ static void read_big_block(PAGECACHE *pagecache,
}
pagecache->big_block_free(&data);
- block_to_read->status&= ~PCBLOCK_BIG_READ;
-
end:
+ block_to_read->status&= ~PCBLOCK_BIG_READ;
if (block_to_read != block)
{
remove_reader(block_to_read);
diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt
index 564e859d146..d271d4c4eb9 100644
--- a/storage/mroonga/vendor/groonga/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/CMakeLists.txt
@@ -240,7 +240,6 @@ include(build/ac_macros/check_functions.m4)
ac_check_symbols(fpclassify math.h)
ac_check_lib(m fpclassify)
-ac_check_lib(dl dlopen)
ac_check_lib(execinfo backtrace)
if(HAVE_LIBEXECINFO)
set(HAVE_BACKTRACE TRUE)
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
index 21628b26ce2..8c71563f722 100644
--- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
@@ -97,7 +97,7 @@ set(GRN_ALL_LIBRARIES
${LZ4_LIBS}
${LIBZSTD_LIBS}
${MESSAGE_PACK_LIBS}
- ${DL_LIBS}
+ ${CMAKE_DL_LIBS}
${M_LIBS}
${WS2_32_LIBS}
${MRUBY_LIBS}
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 92fb49bea8d..b3f84f5eefa 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -688,6 +688,8 @@ my_bool mi_killed_in_mariadb(MI_INFO *info)
static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
{
+ /* This mutex is needed for parallel repair */
+ mysql_mutex_lock(&info->s->intern_lock);
TABLE *table= (TABLE*)(info->external_ref);
table->move_fields(table->field, record, table->field[0]->record_ptr());
if (keynum == -1) // update all vcols
@@ -695,6 +697,7 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
int error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ);
if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED))
error= 1;
+ mysql_mutex_unlock(&info->s->intern_lock);
return error;
}
// update only one key
@@ -703,9 +706,10 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum)
for (; kp < end; kp++)
{
Field *f= table->field[kp->fieldnr - 1];
- if (f->vcol_info)
+ if (f->vcol_info && !f->vcol_info->stored_in_db)
table->update_virtual_field(f);
}
+ mysql_mutex_unlock(&info->s->intern_lock);
return 0;
}
@@ -722,7 +726,7 @@ ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT | HA_CAN_REPAIR |
HA_CAN_TABLES_WITHOUT_ROLLBACK),
- can_enable_indexes(1)
+ can_enable_indexes(0)
{}
handler *ha_myisam::clone(const char *name __attribute__((unused)),
@@ -956,7 +960,7 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param)
if (!table->vfield)
return;
- if (file->s->base.reclength == file->s->vreclength)
+ if (file->s->base.reclength == file->s->vreclength)
{
bool indexed_vcols= false;
ulong new_vreclength= file->s->vreclength;
@@ -964,7 +968,8 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param)
{
if (!(*vf)->stored_in_db())
{
- uint vf_end= (*vf)->offset(table->record[0]) + (*vf)->pack_length_in_rec();
+ uint vf_end= ((*vf)->offset(table->record[0]) +
+ (*vf)->pack_length_in_rec());
set_if_bigger(new_vreclength, vf_end);
indexed_vcols|= ((*vf)->flags & PART_KEY_FLAG) != 0;
}
@@ -982,7 +987,8 @@ void ha_myisam::restore_vcos_after_repair()
{
if (file->s->base.reclength < file->s->vreclength)
{
- table->move_fields(table->field, table->record[0], table->field[0]->record_ptr());
+ table->move_fields(table->field, table->record[0],
+ table->field[0]->record_ptr());
table->default_column_bitmaps();
}
}
@@ -1723,6 +1729,7 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
THD *thd= table->in_use;
ulong size= MY_MIN(thd->variables.read_buff_size,
(ulong) (table->s->avg_row_length*rows));
+ bool index_disabled= 0;
DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
(ulong) rows, size));
@@ -1746,6 +1753,7 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
{
file->update|= HA_STATE_CHANGED;
+ index_disabled= file->s->base.keys > 0;
mi_clear_all_keys_active(file->s->state.key_map);
}
else
@@ -1776,6 +1784,7 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
table->key_info[i].algorithm != HA_KEY_ALG_LONG_HASH)
{
mi_clear_key_active(share->state.key_map, i);
+ index_disabled= 1;
file->update|= HA_STATE_CHANGED;
file->create_unique_index_by_sort= all_keys;
}
@@ -1783,12 +1792,15 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
}
}
else
+ {
if (!file->bulk_insert &&
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
{
mi_init_bulk_insert(file, (size_t) thd->variables.bulk_insert_buff_size,
rows);
}
+ }
+ can_enable_indexes= index_disabled;
DBUG_VOID_RETURN;
}
@@ -1840,6 +1852,7 @@ int ha_myisam::end_bulk_insert()
file->s->state.changed&= ~(STATE_CRASHED|STATE_CRASHED_ON_REPAIR);
}
}
+ can_enable_indexes= 0;
}
DBUG_PRINT("exit", ("first_error: %d", first_error));
DBUG_RETURN(first_error);
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index 2b9724404b7..273de1cd9ca 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -160,7 +160,7 @@ find_package(Threads REQUIRED)
if(WIN32)
set(SYSTEM_LIBS ${SYSTEM_LIBS} Shlwapi.lib Rpcrt4.lib)
else()
- set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBDL})
+ set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${CMAKE_DL_LIBS})
endif()
set(ROCKSDB_LIBS rocksdblib})
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result
index 2139b1bfe05..ac6e2bcc633 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result
@@ -71,16 +71,8 @@ buffer_flush_neighbor buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NU
buffer_flush_neighbor_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages queued as a neighbor batch
buffer_flush_n_to_flush_requested buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages requested for flushing.
buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages target by LSN Age for flushing.
-buffer_flush_adaptive_avg_time_slot buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently per slot.
-buffer_LRU_batch_flush_avg_time_slot buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for LRU batch flushing recently per slot.
-buffer_flush_adaptive_avg_time_thread buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently per thread.
-buffer_LRU_batch_flush_avg_time_thread buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for LRU batch flushing recently per thread.
-buffer_flush_adaptive_avg_time_est buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Estimated time (ms) spent for adaptive flushing recently.
-buffer_LRU_batch_flush_avg_time_est buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Estimated time (ms) spent for LRU batch flushing recently.
-buffer_flush_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for flushing recently.
+buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently.
buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period.
-buffer_LRU_batch_flush_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of LRU batch flushes passed during the recent Avg period.
-buffer_flush_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of flushes passed during the recent Avg period.
buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free.
buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free.
buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening
@@ -106,9 +98,6 @@ buffer_LRU_batch_flush_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL
buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages evicted as part of LRU batches
buffer_LRU_batches_evict buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of LRU batches
buffer_LRU_batch_evict_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages queued as an LRU batch
-buffer_LRU_single_flush_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of single page LRU flush
-buffer_LRU_single_flush_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times single page LRU flush is called
-buffer_LRU_single_flush_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Page scanned per single LRU flush
buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed
buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page
buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search
@@ -183,7 +172,6 @@ log_lsn_current recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0
log_lsn_checkpoint_age recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Current LSN value minus LSN at last checkpoint
log_lsn_buf_pool_oldest recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value The oldest modified block LSN in the buffer pool
log_max_modified_age_async recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Maximum LSN difference; when exceeded, start asynchronous preflush
-log_max_modified_age_sync recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Maximum LSN difference; when exceeded, start synchronous preflush
log_pending_log_flushes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending log flushes
log_pending_checkpoint_writes recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Pending checkpoints
log_num_log_io recovery 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of log I/Os
@@ -234,7 +222,6 @@ innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NU
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
innodb_dict_lru_count_idle server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the idle loop
-innodb_checkpoint_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent by master thread to do checkpoint
innodb_dblwr_writes server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of doublewrite operations that have been performed (innodb_dblwr_writes)
innodb_dblwr_pages_written server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of pages that have been written for doublewrite operations (innodb_dblwr_pages_written)
innodb_page_size server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value InnoDB page size in bytes (innodb_page_size)
diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc
index 3657cc9120d..ec0949b579f 100644
--- a/storage/spider/spd_param.cc
+++ b/storage/spider/spd_param.cc
@@ -3673,7 +3673,7 @@ maria_declare_plugin(spider)
spider_status_variables,
spider_system_variables,
SPIDER_DETAIL_VERSION,
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
},
spider_i_s_alloc_mem_maria,
spider_i_s_wrapper_protocols_maria
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index e7a218bdc47..b84c91efe5f 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -406,7 +406,9 @@ my_copy_fix_mb(CHARSET_INFO *cs,
well_formed_nchars= my_ci_well_formed_char_length(cs, src, src + src_length,
nchars, status);
DBUG_ASSERT(well_formed_nchars <= nchars);
- memmove(dst, src, (well_formed_length= status->m_source_end_pos - src));
+ well_formed_length= status->m_source_end_pos - src;
+ if (well_formed_length)
+ memmove(dst, src, well_formed_length);
if (!status->m_well_formed_error_pos)
return well_formed_length;
diff --git a/strings/json_lib.c b/strings/json_lib.c
index 42bec2c3f79..772f6029e77 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -910,7 +910,7 @@ int json_read_keyname_chr(json_engine_t *j)
case S_QUOTE:
for (;;) /* Skip spaces until ':'. */
{
- if ((c_len= json_next_char(&j->s) > 0))
+ if ((c_len= json_next_char(&j->s)) > 0)
{
if (j->s.c_next == ':')
{
diff --git a/tests/drop_test.pl b/tests/drop_test.pl
index c132c207811..e9b796bd4e5 100755
--- a/tests/drop_test.pl
+++ b/tests/drop_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000 MySQL AB
# Use is subject to license terms
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index a05a9b96679..55e494dcedc 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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 a08044efbd8..157ffc35aef 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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 a90af381376..bb98b8c8577 100644
--- a/tests/fork_big2.pl
+++ b/tests/fork_big2.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/env perl
# Copyright (c) 2002, 2003, 2005, 2006 MySQL AB
# Use is subject to license terms
diff --git a/tests/index_corrupt.pl b/tests/index_corrupt.pl
index dad288d71de..275747d86f8 100755
--- a/tests/index_corrupt.pl
+++ b/tests/index_corrupt.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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 f70bc75fb9a..35ecd52aa2c 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl
index 0dd0fe751aa..b160582d4be 100755
--- a/tests/mail_to_db.pl
+++ b/tests/mail_to_db.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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/mysql_client_test.c b/tests/mysql_client_test.c
index e656b85ab65..7d56a3a7e33 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -8615,7 +8615,8 @@ static void test_mem_overun()
char buffer[10000], field[10];
MYSQL_STMT *stmt;
MYSQL_RES *field_res;
- int rc, i, length;
+ int rc, length;
+ unsigned i;
myheader("test_mem_overun");
@@ -8629,7 +8630,7 @@ static void test_mem_overun()
strxmov(buffer, "create table t_mem_overun(", NullS);
for (i= 0; i < 1000; i++)
{
- sprintf(field, "c%d int", i);
+ sprintf(field, "c%u int", i);
strxmov(buffer, buffer, field, ", ", NullS);
}
length= strlen(buffer);
@@ -20940,6 +20941,153 @@ static void test_explain_meta()
}
+#ifndef EMBEDDED_LIBRARY
+#define MDEV19838_MAX_PARAM_COUNT 32
+#define MDEV19838_FIELDS_COUNT 17
+static void test_mdev19838()
+{
+ int rc;
+ MYSQL_BIND bind[MDEV19838_MAX_PARAM_COUNT];
+ unsigned int i, paramCount = 1;
+ char charvalue[] = "012345678901234567890123456789012345";
+ MYSQL_STMT *stmt;
+
+ myheader("test_mdev19838");
+
+ rc = mysql_query(mysql, "CREATE TABLE mdev19838("
+ "f1 char(36),"
+ "f2 char(36),"
+ "f3 char(36),"
+ "f4 char(36),"
+ "f5 char(36),"
+ "f6 char(36),"
+ "f7 char(36),"
+ "f8 char(36),"
+ "f9 char(36),"
+ "f10 char(36),"
+ "f11 char(36),"
+ "f12 char(36),"
+ "f13 char(36),"
+ "f14 char(36),"
+ "f15 char(36),"
+ "f16 char(36),"
+ "f17 char(36)"
+ ")");
+ myquery(rc);
+
+ stmt = mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ memset(bind, 0, sizeof(bind));
+
+ for (i = 0; i < MDEV19838_MAX_PARAM_COUNT; ++i)
+ {
+ bind[i].buffer = charvalue;
+ bind[i].buffer_type = MYSQL_TYPE_STRING;
+ bind[i].buffer_length = strlen(charvalue) + 1;
+ bind[i].length = &bind[i].length_value;
+ bind[i].length_value = bind[i].buffer_length - 1;
+ }
+
+ for (paramCount = 1; paramCount < MDEV19838_FIELDS_COUNT; ++paramCount)
+ {
+ mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
+
+ rc = mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
+ "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
+ " VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
+
+ /* Expecting an error */
+ DIE_UNLESS(rc != 0);
+
+ mysql_stmt_close(stmt);
+ stmt = mysql_stmt_init(mysql);
+ check_stmt(stmt);
+ }
+
+ paramCount = 0;
+ mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
+ rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838(f1)"
+ " VALUES (?)", -1);
+ /* Expecting an error */
+ DIE_UNLESS(rc != 0);
+ mysql_stmt_close(stmt);
+
+ stmt = mysql_stmt_init(mysql);
+ check_stmt(stmt);
+ /* Correct number of parameters */
+ paramCount = MDEV19838_FIELDS_COUNT;
+ mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
+ mysql_stmt_bind_param(stmt, bind);
+
+ rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
+ "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
+ " VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
+ check_execute(stmt, rc);
+
+ /* MYSQL_TYPE_TINY = 1. This parameter byte can be read as "parameters send" flag byte.
+ Checking that wrong packet is still detected */
+ bind[0].buffer_type = MYSQL_TYPE_TINY;
+ bind[0].length_value = 1;
+ bind[0].buffer_length = 1;
+
+ for (paramCount = 8; paramCount > 0; --paramCount)
+ {
+ mysql_stmt_close(stmt);
+ stmt = mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
+
+ rc = mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
+ "(f1, f2, f3, f4, f5, f6, f7, f8, f9)"
+ " VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
+
+ /* Expecting an error */
+ DIE_UNLESS(rc != 0);
+ }
+
+ /* Test of query w/out parameters, with parameter sent and not sent */
+ for (paramCount = MDEV19838_MAX_PARAM_COUNT; paramCount != (unsigned int)-1; --paramCount)
+ {
+ mysql_stmt_close(stmt);
+ stmt = mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
+
+ if (paramCount > 0)
+ {
+ rc = mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+ }
+
+ rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
+ "(f1)"
+ " VALUES "
+ "(0x1111111111111111)", -1);
+
+ /* Expecting an error if parameters are sent */
+ DIE_UNLESS(rc != 0 || paramCount == 0);
+ }
+
+ mysql_stmt_close(stmt);
+
+ rc = mysql_query(mysql, "drop table mdev19838");
+ myquery(rc);
+}
+#endif // EMBEDDED_LIBRARY
+
+
/*
MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
*/
@@ -21289,6 +21437,9 @@ static struct my_tests_st my_tests[]= {
#endif
{ "test_ps_params_in_ctes", test_ps_params_in_ctes },
{ "test_explain_meta", test_explain_meta },
+#ifndef EMBEDDED_LIBRARY
+ { "test_mdev19838", test_mdev19838 },
+#endif
{ "test_mdev18408", test_mdev18408 },
{ "test_mdev20261", test_mdev20261 },
{ "test_execute_direct", test_execute_direct },
diff --git a/tests/pmail.pl b/tests/pmail.pl
index ef654d99770..441051dee05 100755
--- a/tests/pmail.pl
+++ b/tests/pmail.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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 eef8af642ab..25bc2a3e6aa 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index 8a8028be7ef..fdcd10e8468 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env 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 84381187aa7..d79167dd1b2 100755
--- a/tests/truncate.pl
+++ b/tests/truncate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl -w
+#!/usr/bin/env perl
# Copyright (C) 2002 MySQL AB
# Use is subject to license terms
diff --git a/tpool/tpool.h b/tpool/tpool.h
index 239be53c27e..0d83af5bd74 100644
--- a/tpool/tpool.h
+++ b/tpool/tpool.h
@@ -114,7 +114,7 @@ enum class aio_opcode
AIO_PREAD,
AIO_PWRITE
};
-const int MAX_AIO_USERDATA_LEN= 40;
+constexpr size_t MAX_AIO_USERDATA_LEN= 3 * sizeof(void*);
/** IO control block, includes parameters for the IO, and the callback*/
diff --git a/wsrep-lib b/wsrep-lib
-Subproject ae4e58ba031587039c8830f2f8ca51fa9fb7d6e
+Subproject 2da6e4894e1df5d1db51db2bbc49255e02251b9